2: COMMENT ⊗ VALID 00034 PAGES 3: C REC PAGE DESCRIPTION 4: C00001 00001 5: C00004 00002 BEGIN XGPSER ↔SUBTTL XGPSER SERVICE ROUTINES FOR XEROX GRAPHICS PRINTER 6: C00006 00003 DISPATCH FOR XGPSERVICE 7: C00007 00004 MTAPE UUO for the XGP. 8: C00011 00005 MTAPE UUO 9: C00016 00006 SET ERROR CODE ROUTINES. 10: C00018 00007 INITIALIZATION, RELEASE. 11: C00020 00008 DUMP MODE OUTPUT UUO. 12: C00023 00009 START THE XGP FROM THE PDP-10 13: C00025 00010 SET I-LEVEL DISPATCH AT FIRST UUO. 14: C00027 00011 XGP BUFFERED MODE OUTPUT UUO, CLOSE UUO 15: C00034 00012 XGPIOW START XGP AND WAIT UNTIL IT EMPTIES THE BUFFER 16: C00036 00013 XGPUUO COMMUNICATE TO/FROM THE FONT COMPILER 17: C00038 00014 FONT COMPILER ROUTINES. FCREQ, FCWAIT, XWAKE, XPAUSE,FCWAKE 18: C00043 00015 MORE ROUTINES FOR FC 19: C00047 00016 INTERPROCESSOR COMMUNICATION AT CLOCK LEVEL. HUNG TIMEOUT 20: C00050 00017 User Programming for the XGP 21: C00057 00018 INTERRUPT LEVEL ROUTINES 22: C00064 00019 HERE FOR 'NOT XGPOK' ALSO, QUEUE CUT MARKS. 23: C00066 00020 MODE 17 I-LEVEL 24: C00072 00021 XADV ADVANCE IOWD AT I-LEVEL 25: C00075 00022 BUFFER ADVANCE AT I-LEVEL 26: C00080 00023 Character Mode for the XGP 27: C00091 00024 MODE 0 COMMENTS ABOUT INTERNAL STRUCTURE. 28: C00102 00025 MODE 0 CHANNEL 2 INTERRUPTS 29: C00112 00026 MODE 0 I-LEVEL 'SCAN PHASE' 30: C00116 00027 ROUTINES TO MANIPULATE COMMAND HEADER BLOCKS. 31: C00123 00028 XGP LINE COMPILER CO-ROUTINES 32: C00128 00029 HERE TO QUEUE A TEXT NODE. 33: C00136 00030 MODE 0 GET NEXT CHARACTER 34: C00139 00031 HERE FOR SPECIALS 35: C00141 00032 HERE TO PROCESS RUBOUT 36: C00154 00033 HERE FOR A 'NORMAL' CHARACTER 37: C00158 00034 BEND XGPSER 38: C00159 ENDMK 39: C⊗; 41: BEGIN XGPSER ↔SUBTTL XGPSER SERVICE ROUTINES FOR XEROX GRAPHICS PRINTER 42: ;R. E. GORIN JANUARY, 1973 43: 44: ;BITS FOR THE XGP: 45: 46: ;CONO XGP, 47: 48: SETX←←140000 ;SETS THE COLUMN REGISTER IN INTERFACE 49: SETN←←150000 ;TURNS ON 1 BITS IN INTERFACE 50: SETPI←←160000 ;SET PI CHANNEL, DONENB, BLANK, PAPER,CLRDON 51: DONENB←←100 ;ALLOWS DONE TO BE SET 52: ; BLANK←←40 ;IGNORE BUFFER DATA 53: PAPER←←20 ;TURN ON THE PAPER 54: CLRDON←←10 ;CLEAR DONE 55: SETALL←←SETPI+PAPER+DONENB+CLRDON+XGPCHN 56: ;THIS IS USUAL CONO WHILE SENDING DATA 57: 58: 59: SETCON←←170000 ;ALLOWS SWPBUF,CUTNOW, AND MARKIT COMMANDS 60: SWPBUF←←4 ;SWAP BUFFERS 61: CUTNOW←←2 ;CUT PAPER RIGHT NOW. 62: MARKIT←←1 ;MARK PAPER TO BE CUT LATER. 63: 64: ;CONI XGP, 65: XGPOK←←100 ;INTERFACE AND XGP ARE READY WHEN THIS BIT IS OFF! 66: ; VIDENB←←40 ;VIDEO DATA IS HAPPENING RIGHT NOW. 67: NZ←←20 ;SET WHEN INTERFACE IS READY FOR ANOTHER COMMAND 68: ↑XGPDON←←10 ;DONE. (REFERENCED IN OUTER) 69: 70: ;LH BITS IN XGPIOS 71: XPAPER←←200 ;XGP IS RUNNING PAPER NOW (PAPER UP TO SPEED) 72: XGPERR←←400 ;PDP-6 DETECTED ERROR 73: 74: 75: TNSIZE←←100 ;SIZE OF TEXT NODE 76: VNSIZE←←5 ;VECTOR NODE SIZE 77: 78: 79: ERRMSK←←IOIMPM!IODTER!IODERR!IOBKTL ;ERROR BITS 80: 82: ; DISPATCH FOR XGPSERVICE 83: 84: JRST XGPINI ;SYSTEM INITIALIZATION 85: JRST HUNG ;HUNG TIME OUT 86: ↑XGPDSP: 87: JRST XGPREL ;RELEASE 88: JRST XCLSO ;CLOSE OUTPUT 89: JRST XOUT ;BUFFERED OUTPUT 90: JRST ILLINP ;INPUT ILLEGAL 91: JRST CPOPJ1 ;ENTER 92: JRST CPOPJ1 ;LOOKUP 93: JRST XDMPO ;DUMP MODE OUTPUT 94: JRST ILLINP ;DUMP INPUT 95: POPJ P, ;USETO 96: POPJ P, ;USETI 97: POPJ P, ;UGETF 98: JRST CPOPJ1 ;RENAME 99: POPJ P, ;CLOSE INPUT 100: POPJ P, ;UTPCLR 101: JRST XMTAPE ;MTAPE 102: 103: 104: DWCNT: POINT 6,XGPGCW,35 ;WORD COUNT 105: LNSKIP: POINT 11,XGPGCW,11 106: COLSKP: POINT 12,XGPGCW,23 108: ; MTAPE UUO for the XGP. 109: COMMENT $ 110: 111: MTAPE CHAN,ADR 112: where CHAN is the channel number on which the XGP has been opened is 113: interpreted as follows: 114: ADR contains the operation selector. The data at ADR+1 and 115: following depends on the operation selected. 116: 117: Operation 118: 119: 0 Return error status. 120: ADR+1/ major error code 121: ADR+2,3,4/ error data 122: 123: 1 Font selection. 124: ADR+1/ Font file name in sixbit 125: ADR+2/ Font extension 126: ADR+3/ PPN of font file 127: ADR+4/ font identification number. (0 to 15.) 128: (This UUO will skip if there is no error). 129: 130: The font named will be read by the font compiler. It 131: will be assigned the font identification number that 132: you supply. The identification number is used only 133: by the Font selection operator. 134: 135: 2 Read Margins 136: ADR+1/ Top of page margin 137: ADR+2/ Page body size 138: ADR+3/ Bottom of page margin. 139: ADR+4/ Left margin 140: ADR+5/ Right side margin 141: ADR+6/ Minimum interline space 142: 143: 3 Set Margins 144: ADR+1/ Top of page margin <37777 145: ADR+2/ Page body size <37777 146: ADR+3/ Bottom of page margin. <37777 147: ADR+4/ Left Margin < 3777 148: ADR+5/ Right side margin. Left < Right < 7777 149: ADR+6/ Minimum interline space < 3777 150: 151: If the bottom of page margin is set to 0 then the paper 152: will not be cut. If the page body size is set to 0 then 153: the paper will be cut only when a form feed is encountered. 154: The action of form feed in this case is to space down by the 155: amount specified in the bottom of page margin and then cut. 156: 157: 4 Get status 158: ADR+1/ XGPIOS is returned 159: ADR+2/ -1 if I-level is running, else 0. 160: 161: 5 Pseudo Close. 162: Contents of the system buffer are transmitted to the XGP. 163: XGP is not marked as CLOSEd, but another CLOSE is nearly 164: a no-op. 165: 166: 6 Set Node Counts 167: ADR+1/ The number of Text Nodes (currently =16) 168: ADR+2/ The number of Vector Nodes (Currently =100) 169: Zero in either parameter will use the default. 170: $ 172: ; MTAPE UUO 173: XMTAPE: XCTR XR,[SKIPL TAC,(UUO)] ;N.B. THIS ADDRESS CHECKS BEGINNING OF DATA 174: CAIL TAC,XMTTLN 175: MOVNI TAC,1 176: SKIPG XMTTAB(TAC) ;SKIP UNLESS WE NEED A CLOSE FIRST. 177: TDNN IOS,[DEVSBB,,IOACT] ;DEVICE MUST NOT BE ACTIVE. 178: JRST @XMTTAB(TAC) ;DISPATCH 179: PUSH P,UUO 180: MOVEI UUO,0 ;MAKE THE EFFECTIVE ADDRESS 0 FOR CLOSE. 181: PUSHJ P,XCLSO ;FORCE A CLOSE FIRST 182: POP P,UUO 183: XCTR XR,[MOVE TAC,(UUO)] ;GET DISPATCH AGAIN (CAN'T BE WRONG) 184: JRST @XMTTAB(TAC) 185: 186: CPOPJ 187: XMTTAB: XMTP0 188: SETZ XMTP1 189: XMTP2 190: SETZ XMTP3 191: XMTP4 192: XCLSP ;FORCE DATA TRANSMISSION, PSEUDO CLOSE. 193: SETZ XMTP6 ;SET NODE COUNTS 194: XMTTLN←←.-XMTTAB 195: 196: XMTP0: XCTR XR,[MOVE TAC,4(UUO)] ;ADDRESS CHECK LAST WORD (FIRST WORD IS OK) 197: HRRI TAC1,1(UUO) ;DESTINATION 198: PUSHJ P,RELOCA ;RELOCATE DESTINATION 199: JRST ADRERR ;ADDRESS CHECK 200: JUMPL TAC1,ADRERR ;WRITE PROTECTED 201: HRLI TAC1,XGPERC ;SOURCE 202: MOVEI TAC,3(TAC1) 203: BLT TAC1,(TAC) 204: SETZM XGPERC ;CLEAR ERROR COUNT 205: POPJ P, 206: 207: XMTP1: XCTR XR,[MOVE TAC,4(UUO)] ;ADDRESS CHECK THE END OF THE TRANSFER 208: MOVEI TAC1,1(UUO) ;RELATIVE FIRST LOC OF SOURCE 209: PUSHJ P,RELOCA 210: JRST ADRERR 211: MOVSI TAC,(TAC1) ;SWAP TO SOURCE 212: HRRI TAC,XGPNST+1 ;DESTINATION 213: BLT TAC,XGPNST+4 214: 215: MOVEI TAC,2 ;OP CODE FOR FONT COMPILER. 216: MOVEM TAC,XGPNST 217: PUSHJ P,FCREQ 218: POPJ P, ;LOSE ERROR CODE WILL BE SET ALREADY 219: MOVE TAC,XGPOST ;GET OLD STATUS 220: CAIE TAC,2 ;EXPECTED REPLY IS YESSIR 221: JRST FCERRX ;OOPS FC REPLIED WRONG. 222: MOVE TAC,XGPOST+1 ;GET RELATIVE ADDRESS OF FONT TABLE 223: MOVE TAC1,XGPNST+4 ;GET FONT NUMBER THAT WE TOLD THE FC. 224: MOVEM TAC,XFTADR(TAC1) 225: JRST CPOPJ1 226: 227: XMTP2: XCTR XR,[MOVE TAC,6(UUO)] ;ADDRESS CHECK LAST WORD (FIRST WORD IS OK) 228: MOVEI TAC1,1(UUO) ;DESTINATION 229: PUSHJ P,RELOCA 230: JRST ADRERR 231: JUMPL TAC1,ADRERR 232: HRLI TAC1,XGPPS1 ;SOURCE 233: MOVEI TAC,5(TAC1) ;LAST WORD OF DESTINATION 234: BLT TAC1,(TAC) 235: POPJ P, 236: 237: XMTP3: MOVEI TAC1,0 238: XMTP3A: XCTR XR,[MOVE TAC,1(UUO)] 239: ANDI TAC,37777 240: MOVEM TAC,XGPPS1(TAC1) 241: ADDI UUO,1 242: CAIGE TAC1,2 243: AOJA TAC1,XMTP3A 244: XCTR XR,[MOVE TAC,1(UUO)] ;LEFT MARGIN 245: ANDI TAC,3777 246: MOVEM TAC,XGPLMR 247: XCTR XR,[MOVE TAC,2(UUO)] ;RIGHT MARGIN 248: ANDI TAC,7777 249: CAMG TAC,XGPLMR 250: MOVEI TAC,7777 251: MOVEM TAC,XGPRMR 252: XCTR XR,[MOVE TAC,3(UUO)] 253: ANDI TAC,3777 254: MOVEM TAC,XGPILS 255: POPJ P, 256: 257: XMTP4: MOVE IOS,XGPIOS 258: XCTR XW,[MOVEM IOS,1(UUO)] 259: MOVE TAC,XGPIGO 260: XCTR XW,[MOVEM TAC,2(UUO)] 261: POPJ P, 262: 263: XMTP6: XCTR XR,[SKIPG TAC,1(UUO)] ;GET THE TEXT NODE COUNT 264: MOVEI TAC,NTNODE 265: MOVEM TAC,XNTNOD 266: XCTR XR,[SKIPG TAC,2(UUO)] 267: MOVEI TAC,NVNODE 268: MOVEM TAC,XNVNOD 269: POPJ P, 271: ; SET ERROR CODE ROUTINES. 272: XERR1: JSP TAC,XERRC ;FC LOSSAGE: JOB CAPACITY EXCEEDED 273: XERR2: JSP TAC,XERRC ;FC LOSSAGE: NO INITIAL RESPONSE. 274: XERR3: JSP TAC,XERRC ;FC LOSSAGE: NO INTERMEDIATE RESPONSE. 275: XERR4: JSP TAC,XERRC ;FC LOSSAGE: ILLEGAL RESPONSE. 276: XERR5: JSP TAC,XERRC ;I-LEVEL DATA MISSED. - BUFFERED MODE. 277: XERR6: JSP TAC,XERRC ;XGP IS HUNG - HUNG TIMEOUT. 278: XERR7: JSP TAC,XERRC ;ILLEGAL MODE. 279: XERR10: JSP TAC,XERRC ;LINE COMPILER ERROR. LINE TOO COMPLEX. 280: XERR11: JSP TAC,XERRC ;OUT OF ORDER 281: XERR12: JSP TAC,XERRC ;I MISSED IT! 282: XERR13: JSP TAC,XERRC ;PAGE TOO LONG 283: XERR14: JSP TAC,XERRC ;ILLEGAL VECTOR PARAMETERS 284: 285: XERRC: SKIPE XGPERC ;ONLY LET ONE ERROR THROUGH 286: POPJ P, ; 287: SUBI TAC,XERR1 288: HRRZM TAC,XGPERC ;SET ERROR CODE FOR USER. 289: XERRCL: SETZM XGPERC+1 ;AND CLEAR EXTRA ERROR WORDS. 290: SETZM XGPERC+2 291: SETZM XGPERC+3 292: POPJ P, 293: 294: FCERRX: PUSHJ P,XERR4 ;SET ERROR CODE. 295: MOVE TAC,[XGPOST,,XGPERC+1] ;GET FC STATUS 296: BLT TAC,XGPERC+3 ;STORE FC STATUS AS 3 EXTRA ERROR WORDS. 297: POPJ P, 299: ; INITIALIZATION, RELEASE. 300: 301: XGPINI: SYNINI XGPCSC ;INITIALIZE XGP SYNCHRONIZATION CELLS. 302: SETZM XFLAPC ;FLAPPER COUNT 303: SETZM XFLAPB ;FLAPPER BITS 304: SETZM XFLAPA ;MORE FLAPPER BITS 305: SETZM XCUTQ 306: MOVE TAC,[POINT 36,XCUTQ-1,35] 307: MOVEM TAC,XCUTBP 308: SETZM XIBUF ;THERE IS NO INTERNAL BUFFER FOR DEVICE. 309: 310: XCPIN1: SETZM XGPGO ;NO ONE READY TO XFER DATA. 311: SETZM XGPHDW ;ZERO HEADER IOWD 312: SETZM XGPAT2 313: SETZM XGPMDP ;INITIALIZE DUMP MODE STUFF 314: SETZM XGPNXC 315: SETZM XGPBIG 316: SETZM XGPIWD 317: SETZM XGPERC ;CLEAR ERROR CODE. 318: MOVE TAC,[XMSET,,XGPPS1] 319: BLT TAC,XGPBLN 320: JRST XERRCL ;CLEAR MINOR ERROR CODES AND RETURN 321: 322: 323: ↑XGPIN2: ;P2 INITIALIZE THE XGP. 324: MOVSI IOS,XPAPER 325: PUSHJ P,XGPCLR 326: SETZM P2CH2 ;SO XGPP2 WILL START XGP NOW. 327: SETOM XGPP2F ;LET CLOCK LEVEL START US. 328: JRST XGPP2 ;RUN OUR CLOCK LEVEL AND RETURN TO SYSINI 329: 330: 331: XGPREL: SETOM XGPKIL 332: PUSHJ P,FCKILL ;KILL THE FONT COMPILER 333: SKIPE AC1,XIBUF 334: PUSHJ P,FSGIVE 335: SETZM XIBUF 336: PUSHJ P,PSYNCX ; 337: SETZM XGPBIT ;TELL PDP-6 THAT WE DON'T HAVE ANY MORE. 338: MOVE IOS,[XGPERR!IOW!DEVSBB!IOBEG!IOEND,,ERRMSK!IOACT] 339: ANDCAM IOS,XGPIOS 340: PUSHJ P,XSYNCX ;RELEASE SYNCHRONIZER 341: JRST XCPIN1 342: 344: ; DUMP MODE OUTPUT UUO. 345: XDMPO2: TRNE IOS,ERRMSK 346: POPJ P, ;DON'T WAIT IF HE'S GOT ERROR BITS ON. 347: PUSHJ P,WSYNC ;STOP FOR A WHILE. (SETS IOW) 348: XDMPO: SKIPE XGPNXC ;IS THERE A 'NEXT' COMMAND ALREADY? 349: JRST XDMPO2 ;YES. WAIT UNTIL THERE ISN'T ONE 350: 351: PUSHJ P,COMCHK ;CHECK COMMAND LIST 352: JRST ADRERR ;ADDRESS ERROR IN COMMAND. 353: MOVE J,JOB(PID) ;FIX J, CLOBBERED BY COMCHK 354: ;UUO POINTS TO FIRST COMMAND IOWD OR 0. 355: HRRZ TAC,UUO ;COMMAND LIST POINTER 356: HRLI TAC,PROG 357: SKIPN @TAC ;GET ACTUAL COMMAND WORD. 358: POPJ P, ;NULL COMMAND LIST. DO NOTHING. 359: MOVEM TAC,XGPNXC ;POINTER TO COMMAND SAVED AS 'NEXT COMMAND' 360: SKIPE XGPMDP ;IS THERE A CURRENT MAIN POINTER? 361: JRST XDMPO5 ;YES. 362: SETZM XGPNXC ;XGP IS IDLE, CLEAR NEXT 363: SUBI TAC,1 364: MOVEM TAC,XGPMDP ;AND SET MAIN. 365: XDMPO5: PUSHJ P,PSYNCX 366: MOVE IOS,XGPIOS 367: TLZE IOS,IOBEG ;IF IOBEG, 368: PUSHJ P,SETXIO ;SET I-LEVEL DATA DISPATCH. 369: TRNE IOS,ERRMSK 370: JRST XSYNCX ;IN CASE OF ERROR, DESYNCHRONIZE AND RETURN 371: PUSHJ P,XSYNCX 372: PUSHJ P,XGPSTR ;START THE XGP. (DON'T CLOBBER J,PROG) 373: PUSHJ P,PSYNCX 374: MOVE IOS,XGPIOS 375: TRNE IOS,ERRMSK 376: JRST XSYNCX ;FLUSH ERRORS. 377: MOVEM PROG,XGPROG ;SET UP FOR XADV 378: PUSHJ P,SETACT 379: PUSHJ P,XSYNCX 380: SETOM XGPGO ;TELL PDP-6 TO START DOING DATA. 381: TRNE IOS,100 ;CONTINUOUS MODE? 382: JRST TPOPJ ;AVOID CALLING WSYNC IN UUOCON 383: XDMPO8: PUSHJ P,WAIT1 ;RETURN WHEN IOACT OFF. 384: XDMPO1: SETZM XGPGO 385: PUSHJ P,PSYNCX 386: SETZM XGPBIT 387: JRST XSYNCX 389: ; START THE XGP FROM THE PDP-10 390: XGPSTR: SETZM XGPKIL ;HERE TO START THE XGP 391: SETZM XGPAOK ; 392: XGSTR1: PUSHJ P,PSYNCX 393: SETOM XGPCNY ;IF PAPER IS MOVING, I-LEVEL JUMPS TO PAPOON. 394: SETOM XGPBIT ;TELL PDP-6 WE WANT PAPER MOTION. 395: LDB TAC,PDVTIM 396: DPB TAC,PDVCNT 397: MOVE IOS,XGPIOS ;GET CURRENT STATE OF AFFAIRS 398: TDNE IOS,[DEVSBB,,IOACT] ;IS THE BEAST RUNNING NOW? 399: JRST XGSTR4 ;YES. RETURN QUICK 400: PUSHJ P,XSIOS ;SET IOS RIGHT. 401: PUSHJ P,XSYNCX 402: LDB J,PJOBN 403: MOVNI IOS,DIOWQ ;REQUEUE TO DIOW TO ALLOW SYNC. 404: MOVEM IOS,JOBQUE(J) 405: XGSTR2: PUSHJ P,WSCHED ;RESCHEDULE. 406: MOVE IOS,XGPIOS 407: TLNE IOS,IOW ;DID THE RIGHT GUY BRING ME OUT? 408: JRST XGSTR2 ;NO. WAIT SOME MORE. 409: TRNE IOS,ERRMSK ;ANY ERRORS? 410: POPJ P, ;YES. RETURN THEM 411: PUSHJ P,PSYNCX 412: PUSHJ P,XSIOS ;SET SOME GOOD BITS IN XGPIOS. 413: XGSTR4: TLO IOS,IO!IOW 414: TRNE IOS,100 ;OVERLAPPED MODE? 415: TLZ IOS,IOW ;YES. THEN NOT REALLY IN IOW. 416: MOVEM IOS,XGPIOS 417: JRST XSYNCX ;RETURN. PAPER IN MOTION. 418: 419: XSIOS: MOVSI IOS,IOW!IO!DEVSBB ;ASSUME BUFFERED MODE 420: MOVE TAC,XGPDDB+DEVCMR 421: TLNN TAC,DEVIBF ;SKIP IF REALLY BUFFERED MODE 422: TDC IOS,[DEVSBB,,IOACT] ;FLUSH DEVSBB, TURN ON IOACT FOR DUMP MODE. 423: IORB IOS,XGPIOS ;SET THOSE BITS. 424: POPJ P, 426: ; SET I-LEVEL DISPATCH AT FIRST UUO. 427: SETXIO: LDB TAC,PIOMOD 428: MOVE TAC,XIODSP(TAC) 429: TRNE IOS,100 ;SPECIAL MODE? 430: MOVS TAC,TAC 431: HRRZM TAC,XDISP2 ; 432: TRNE TAC,-1 ;SKIP IF ZERO DISPATCH 433: JRST SETXI1 434: TRO IOS,IOIMPM ;ILLEGAL. 435: PUSHJ P,XERR7 436: SETXI1: MOVEM IOS,XGPIOS 437: LDB TAC,PIOMOD 438: MOVE IOS,XGPDDB+DEVCMR 439: CAIL TAC,D 440: TLZA IOS,DEVIBF ;NO INTERNAL BUFFER IN DUMP MODE 441: TLO IOS,DEVIBF ;INTERNAL BUFFER IN BUFFERED MODE. 442: MOVEM IOS,XGPDDB+DEVCMR 443: MOVE IOS,XGPIOS 444: POPJ P, 445: 446: XIODSP: 0,,XCIBEG ;MODE 0 447: 0,,XCIBEG ;MODE 1 448: 0 ;MODE 2 449: 0 ;MODE 3 450: 0 ;MODE 4 451: 0 ;MODE 5 452: 0 ;MODE 6 453: 0 ;MODE 7 454: 0 ;MODE 10 455: 0 ;MODE 11 456: 0 ;MODE 12 457: 0,,XCIBEG ;MODE 13 - SAME AS MODE 0 458: 0 ;MODE 14 459: 0 ;MODE 15 460: 0 ;MODE 16 461: XDI,,XDI ;MODE 17 462: 463: XGPSET: PUSHJ P,PSYNCX 464: IORB IOS,XGPIOS 465: XSYNCX: XSYNC XGPCSC 466: POPJ P, 467: 468: XGPCLR: PUSHJ P,PSYNCX 469: ANDCAB IOS,XGPIOS 470: JRST XSYNCX 471: 472: PSYNCX: PSYNC XGPCSC 473: POPJ P, 475: ; XGP BUFFERED MODE OUTPUT UUO, CLOSE UUO 476: XCLSP: MOVEI UUO,0 ;KLUDGE FOR MTAPE 5. 477: XCLSO: MOVSI IOS,IOEND ;FLAG CLOSE UUO. 478: PUSHJ P,XGPSET 479: LDB TAC,PIOMOD ;GET THE MODE. 480: CAIL TAC,SD ;IS THIS A DUMP MODE? 481: JRST XDMPO8 ;YES. WAIT FOR ALL IO AND STOP XGP 482: PUSHJ P,OUT ;DO ONE MORE OUTPUT. 483: MOVSI IOS,IOBEG ;NOW, READY TO INITIALIZE AGAIN. 484: JRST XGPSET ;SET IOBEG IN DEVIOS AND RETURN. 485: 486: XOUT: MOVEI IOS,ERRMSK ;CLEAR ANY ERRORS 487: PUSHJ P,XGPCLR ;... 488: TLNN IOS,IOBEG ;FIRST OPERATION? 489: JRST XOUT1 ;NO. 490: MOVE AC3,XGPBLN 491: SKIPN AC1,XIBUF ;IN CASE SOMEONE LEFT IT HERE 492: PUSHJ P,UFSGET ;GET A BLOCK OF FREE STORAGE. 493: MOVEM AC1,XIBUF ;FIRST LOC OF BUFFER. 494: MOVEM AC1,XTAKE ;TAKE POINTER 495: MOVEM AC1,XPUT ;PUT POINTER 496: SETZM XBFCNT ;BUFFER COUNT. 497: ADD AC1,XGPBLN 498: MOVEM AC1,XIBFND ;END OF BUFFER+1 499: PUSHJ P,NFONT ;IF WE NEED A FONT, GET ONE. 500: JRST F.LOSE ;(N.B. DON'T CLEAR IOBEG!) 501: PUSHJ P,PSYNCX 502: MOVE IOS,XGPIOS ;ONCE THIS IS SET UP,... 503: TLZ IOS,IOBEG ;NOW, NO LONGER THE BEGINNING 504: PUSHJ P,SETXIO 505: PUSHJ P,XSYNCX 506: XOUT1: MOVE IOS,XGPIOS ;IF ERRORS, REPORT THEM TO USER 507: TRNE IOS,ERRMSK ;DON'T TRY TO GO ON. 508: POPJ P, 509: PUSHJ P,DEVSTU ;SET UP TO PROCESS THIS BUFFER 510: JRST XOUT3 ;BUFFER IS ALREADY EMPTY? 511: CAMLE AC2,XGPBLN ;COULD IT EVER FIT? 512: JRST XBTLRR ;NO. FLUSH LOSER. 513: JUMPE AC2,XOUT2A ;TAKE 2 GIANT STEPS IF EMPTY BUFFER 514: MOVE TAC,XGPBLN 515: SUB TAC,XBFCNT ;TAC←SPACE REMAINING. 516: CAILE AC2,(TAC) ;IS THERE SPACE ENOUGH? 517: JRST XOUT4 ;NO ROOM. WE HAVE TO WAIT 518: MOVE TAC,XPUT 519: CAMGE TAC,XTAKE 520: JRST XOUT2 ;PUT<TAKE DATA FITS FROM PUT TO TAKE 521: ;WE NEED TO DO ONLY ONE BLT. 522: 523: MOVE TAC1,XIBFND ;POINTER TO THE END OF THE BUFFER+1 524: SUBI TAC1,(TAC) ;CALCULATE SPACE TO THE END. 525: CAIL TAC1,(AC2) ;COMPARE WITH DATA SIZE... 526: JRST XOUT2 ;ONE BLT WILL SUFFICE. 527: 528: HRLI TAC,(AC3) ;S,,D FOR BLT 529: MOVE AC1,XIBFND ;END OF THE BLT+1 530: BLT TAC,-1(AC1) ;FROM USER THRU THE END OF THE BUFFER. 531: MOVE TAC,XIBUF ;NEW XPUT INTO TAC. 532: ADDI AC3,(TAC1) ;MAKE NEW POINTER TO USER. 533: SUBI AC2,(TAC1) ;MAKE NEW COUNT. 534: PUSHJ P,PSYNCX 535: ADDM TAC1,XBFCNT ;INCREMENT THE BUFFER USE COUNT. 536: PUSHJ P,XSYNCX 537: XOUT2: HRLI TAC,(AC3) ;DATA WILL FIT UPWARDS FROM PUT. 538: MOVEI AC1,(TAC) ;S,,D IN TAC. D IN AC1. 539: ADDI AC1,(AC2) ;COMPUTE LAST DESTINATION OF BLT+1 540: BLT TAC,-1(AC1) ;MOVE DATA. 541: CAML AC1,XIBFND ;IS POINTER AT THE END NOW? 542: MOVE AC1,XIBUF ;YES. WRAP BACK TO FRONT. 543: MOVEM AC1,XPUT ;SAVE THE NEW PUT POINTER. 544: PUSHJ P,PSYNCX 545: ADDM AC2,XBFCNT ;INCREMENT BUFFER SIZE. 546: PUSHJ P,XSYNCX 547: XOUT2A: PUSHJ P,ADVBFE ;ADVANCE THE OUTPUT BUFFER 548: JRST XOUT3 ;NO MORE DATA THERE. 549: JRST XOUT1 ;PROCESS NEXT BUFFER FULL. 550: 551: XOUT3: ;HERE IF SYSTEM BUFFER IS NOT FULL. 552: TLNE IOS,IOEND ;IS THIS THE LAST UUO? 553: SKIPG XBFCNT ;LAST UUO. IS THERE DATA TO SEND? 554: POPJ P, ;NO DATA OR NOT LAST (LET USER ADD MORE). 555: SETZM XGPWSZ ;ZERO WAITING SIZE ⊃ LAST UUO. 556: ;XGP WILL RESDUCE XBFCNT TO 0 BEFORE 557: ;REACTIVATING P1. 558: PUSHJ P,XGPIOW ;YES. START XGP AND WAIT. 559: JRST F.LOSE ;FONT COMPILER LOSES 560: POPJ P, ;HERE WE LOST WITH XGP ERROR. 561: MOVSI IOS,IOEND ;NO LONGER LAST UUO. 562: PUSHJ P,XGPCLR ;CLEAR BIT. 563: JRST XDMPO1 ;CLEAR OUT REMAINING BITS AND CELLS. 564: 565: 566: XOUT4: ;HERE IF SYSTEM BUFFER TOO FULL. 567: SUB AC2,XGPBLN 568: MOVNM AC2,XGPWSZ ;WHEN XBFCNT≤XGPWSZ, P2 REACTIVATES P1. 569: ;SPACE THAT WE'LL NEED. 570: TLNN IOS,IOEND ;LAST UUO? 571: PUSHJ P,DEVCR ;NOT LAST. CHECK BUFFER RING USE BIT. 572: JRST XOUT5 ;USER HAS NO FREE BUFFERS. OR CLOSE UUO 573: POPJ P, ;WAIT UNTIL USER FILLS ALL HIS BUFFERS. 574: XOUT5: PUSHJ P,XGPIOW ;USER HAS NO FREE BUFFERS. START XGP. WAIT. 575: JRST F.LOSE ;FONT COMPILER LOSES 576: POPJ P, ;WE LOST WITH XGP HUNG. 577: JRST XOUT1 ;SYSTEM BUFFER ¬FULL. GOBBLE USER BUFFER. 578: 579: 580: XBTLRR: SETOM XGPKIL ;STOP THE XGP. GRIND. ARRGH. 581: JRST BTLERR ;GIVE USER A MESSAGE. 583: ; XGPIOW START XGP AND WAIT UNTIL IT EMPTIES THE BUFFER 584: 585: XGPIOW: 586: SKIPE XGPBIT ;ARE WE TELLING PDP-6 WE WANT PAPER? 587: JRST XGPIO1 ;YES. THEN PAPER MUST BE GOING. 588: ;NO IT'S TIME TO START XGP. 589: SKIPG XFCJN ;DOES FC EXIST? 590: JRST XGPIO0 ;NO SO DON'T LOCK IT 591: PUSHJ P,FCLOCK 592: POPJ P, 593: XGPIO0: PUSHJ P,XGPSTR ;START THE XGP. 594: MOVE IOS,XGPIOS 595: TRNE IOS,ERRMSK 596: JRST CPOPJ1 ;ERRORS. TELL LOSER. 597: XGPIO1: MOVSI IOS,IOW!DEVSBB ;IOWAIT, SYSTEM BUFFER BUSY 598: PUSHJ P,XGPSET 599: SETOM XGPGO ;DATA IS IN CORE (SYSTEM) AND READY. 600: MOVNI TAC,DIOWQ ;REQUE TO DEVICE WAIT... 601: MOVEM TAC,JOBQUE(J) 602: PUSHJ P,WSCHED 603: MOVE IOS,XGPIOS 604: TLNE IOS,IOW ;REALLY DONE? 605: JRST XGPIO1 ;NO 606: JRST CPOPJ2 ;YES 608: ; XGPUUO COMMUNICATE TO/FROM THE FONT COMPILER 609: ; CALLED BY CALL AC,['XGPUUO'] 610: 611: ; AC LEFT POINTS TO FC CURRENT STATUS BLOCK. (20 WORDS) 612: ; AC RIGHT POINTS TO FC NEW STATUS BLOCK.(20 WORDS) 613: ; IF THERE IS NO NEW STATUS, JOB WILL BE REQUEUED TO WAIT. 614: 615: ↑XGPUUO: 616: MOVE TAC,JBTPRV(J) 617: TLNN TAC,XGPPRV 618: POPJ P, ;WRONG CREDENTIALS. 619: 620: SETZM XGPOST ;ASSUME BY DEFALT, NULL OLD STATUS. 621: XCTR XR,[HLRZ TAC,(UCHN)] ;GET THE OLD SATAUS ADDRESS. 622: JUMPE TAC,XGPUU1 ;JUMP IF THERE IS NO OLD STATUS 623: MOVEI TAC1,17(TAC) ;CHECK ENDING ADDRESS FOR LEGALITY 624: XCTR XR,[MOVE TAC1,(TAC1)] ;WE LOSE CONTROL ON ADDRESS CHECK. 625: ADDI TAC,(PROG) ;ADDRESS OF NEW STATUS. 626: MOVSI TAC,(TAC) ;SOURCE 627: HRRI TAC,XGPOST ;OLD STATUS BLOCK 628: BLT TAC,XGPOST+17 ;GOBBLE OLD STATUS 629: XGPUU1: PUSHJ P,XWAKE ;REPORT OLD STATUS TO ONE WHO WAITS. 630: PUSHJ P,XPAUSE ;AND PUT US TO BED. 631: XCTR XR,[HRRZ TAC,(UCHN)] ;GET THE NEW STATUS ADDRESS. 632: JUMPE TAC,XGPUU2 ;JUMP IF NO NEW STATUS BLOCK. 633: MOVEI TAC1,17(TAC) ;CHECK ENDING ADDRESS FOR LEGALITY 634: XCTR XR,[MOVE TAC1,(TAC1)] 635: HRLI TAC,XGPNST ;NEW STATUS BLOCK 636: ADDI TAC,(PROG) 637: MOVEI TAC1,17(TAC) 638: BLT TAC,(TAC1) 639: XGPUU2: POPJ P, 641: ; FONT COMPILER ROUTINES. FCREQ, FCWAIT, XWAKE, XPAUSE,FCWAKE 642: ; NEW STATUS FOR XGP HAS TO BE SET UP BEFORE CALL. 643: 644: FCREQX: POP P,J 645: MOVE PROG,JBTADR(J) 646: JRST XERR1 ;LOSE BECAUSE OF JOB CAPACITY EXCEEDED 647: 648: FCREQ: SKIPE XFCJN ;DOES FC EXIST? 649: JRST FCREQ1 ;YES. JUST WAKE IT UP. 650: PUSH P,J ;CREATE A FONT COMPILER 651: PUSHJ P,INIJOB ;ATTEMPT TO GLOM A JOB SLOT 652: JRST FCREQX ;NONE AVAILABLE 653: JRST FCREQX ;WAIT FOR FREE STORAGE. (CAN'T HAPPEN). 654: MOVE AC3,['XGPSYS'] ;PPN OF FONT COMPILER. 655: MOVEM AC3,PRJPRG(J) 656: MOVEM AC3,JOBPPN(J) 657: MOVE AC1,['[-FC-]'] ;NAME OF FONT COMPILER. 658: MOVEM AC1,JOBNAM(J) 659: IFN FTSTAT,<PUSHJ P,NAMSTT> 660: MOVSI AC1,XGPPRV 661: MOVEM AC1,JBTPRV(J) 662: MOVEM AC1,JB2PRV(J) ;ALSO PASSIVE ONES 663: MOVSI AC1,JNA 664: IORM AC1,JBTSTS(J) 665: MOVEM J,XFCJN 666: LSH J,=12 667: ADD J,[GETBT0,,1] ;PLANT CLOCK REQUEST. 668: CONO PI,PIOFF 669: IDPB J,CLOCK 670: CONO PI,PION 671: POP P,J ;RESTORE J AND WAIT. 672: MOVE PROG,JBTADR(J) ;RESET THIS 673: PUSHJ P,FCWAIT ;AND WAIT FOR IT TO TELL US 'READY' 674: JRST XERR2 ;OOPS. 675: FCREQ1: MOVE TAC,PRJPRG(J) 676: MOVEM TAC,XGPNST+17 ;SET USER PPN AS PART OF NEW STATUS 677: MOVEM J,XGPNST+16 ;AND USER JOB NUMBER TOO. 678: PUSHJ P,FCWAKE ;WAKE THE FONT COMPILER. GIVE IT NEW STATUS 679: PUSHJ P,FCWAIT ;WAIT FOR FC TO RESPOND 680: JRST XERR3 ;OOPS. 681: JRST CPOPJ1 ;CALLER WILL INSPECT FC STATUS. 682: 683: 684: FCWAIT: MOVE TAC,XCLKNM 685: LSH TAC,=12 686: ADD TAC,[FCRQCK,,=60*JIFSEC] 687: CONO PI,PIOFF 688: IDPB TAC,CLOCK 689: CONO PI,PION 690: ;HERE XGPSER WAITS FOR FC (OR TIMEOUT) 691: SETOM XGPFC1 ;FLAG THAT WE ARE WAITING FOR FC 692: SETZM FCRQER ;INITIALLY, NO ERROR. 693: FCWAT1: MOVNI TAC,IOWQ 694: MOVEM TAC,JOBQUE(J) 695: PUSHJ P,WSCHED ;DELAY 696: SKIPE XGPFC1 ;IS THIS WAKEUP LEGITIMATE? 697: JRST FCWAT1 ;NO. WAIT MORE. 698: SKIPE FCRQER ;CLOCK TIME OUT? 699: POPJ P, ;YES. FAILURE. (OOPS) 700: AOS TAC,XCLKNM ;CANCEL THE CLOCK REQUEST. 701: CAILE TAC,77 702: SETZM XCLKNM 703: JRST CPOPJ1 ;RETURN SUCCESS. 704: 705: FCRQCK: CAME TAC,XCLKNM 706: POPJ P, 707: SETOM FCRQER ;CLOCK ERROR 708: ;HERE FC (OR TIMEOUT) WAKES XGPSER 709: XWAKE: SETZM XGPFC1 ;XGP NOT WAITING FOR FC ANY MORE. 710: PUSH P,J 711: MOVEI DDB,XGPDDB 712: LDB J,PJOBN 713: JUMPE J,XWAKE1 714: SKIPL JBTSTS(J) ;DON'T START HIM IF HE CANT RUN 715: JRST XWAKE1 716: MOVNI TAC,RUNQ 717: MOVEM TAC,JOBQUE(J) 718: PUSHJ P,REQUE 719: XWAKE1: POP P,J 720: POPJ P, 721: 722: ;HERE THE FC WAITS FOR XGPSER 723: XPAUSE: SETOM XGPFC2 ;FC WAITS FOR SYSTEM 724: HRRZM PROG,XFCADR ;SAVE REL ADDRESS OF FC 725: MOVNI TAC,IOWQ 726: MOVEM TAC,JOBQUE(J) 727: PUSHJ P,WSCHED 728: SKIPE XGPFC2 729: JRST XPAUSE ;WOKEN FOR THE WRONG REASON 730: POPJ P, 731: 732: ;HERE XGPSER WAKES UP THE FC 733: FCWAKE: PUSH P,J ;WAKE UP FC 734: SETZM XGPFC2 ;FC NOT WAITING FOR SYSTEM ANY MORE 735: SKIPLE J,XFCJN ;SKIP IF THERE'S NO SUCH JOB 736: SKIPL JBTSTS(J) ;JOB EXISTS. SKIP IF IT CAN BE RUN 737: JRST XWAKE1 ;CANT RUN OR NO SUCH JOB 738: MOVNI TAC,RUNQ 739: MOVEM TAC,JOBQUE(J) 740: PUSHJ P,REQUE 741: JRST XWAKE1 742: 744: ; MORE ROUTINES FOR FC 745: FCLOCK: MOVEI TAC,3 746: MOVEM TAC,XGPNST 747: PUSHJ P,FCREQ 748: POPJ P, ;TIME OUT. ERROR CODE IS SET ALREADY 749: SKIPE XGPOST ;EXPECTED REPLY IS 'READY' 750: JRST FCERRX ;BARF! SET EXTENDED ERRORS 751: JRST CPOPJ1 752: 753: FCKILL: SETZM XGPNST 754: SETZM XFTADR ;CLEAR OUT OUR MEMORY OF OLD FONTS 755: MOVE TAC,[XFTADR,,XFTADR+1] 756: BLT TAC,XFTADR+17 757: SKIPG TAC,XFCJN ;GET OLD JOB NUMBER 758: POPJ P, 759: MOVSI TAC1,XGPPRV 760: IFE FTSTAT,< 761: TDNE TAC1,JBTPRV(TAC) ;ARE WE SURE THIS IS THE RIGHT JOB? 762: SETZM JOBNAM(TAC) ;YES. CLEAR JOB NAME. 763: >;IFE FTSTAT 764: IFN FTSTAT,< 765: TDNN TAC1,JBTPRV(TAC) 766: JRST $FCKIL 767: SETZM JOBNAM(TAC) 768: PUSH P,J 769: MOVE J,TAC 770: PUSHJ P,NAMSTT 771: POP P,J 772: $FCKIL: 773: >;FTSTAT 774: ANDCAM TAC1,JBTPRV(TAC) ;CLEAR OUT PRIVILEGES 775: PUSHJ P,FCWAKE ;WAKE HIM UP TO DIE. 776: SETZM XFCJN 777: POPJ P, 778: 779: XBIDSP: 4001 ;BITS ON FOR MODES THAT NEED FONTS 780: 781: NFONT: LDB TAC,PIOMOD ;GET THE MODE AGAIN 782: MOVEI TAC1,1 783: LSH TAC1,(TAC) 784: TDNN TAC1,XBIDSP ;NEEDING A FONT? 785: JRST CPOPJ1 ;NO. 786: MOVEI TAC,1 ;ALLOCATE COMMAND 787: MOVEM TAC,XGPNST 788: MOVE TAC,XNTNOD ;NUMBER OF TEXT NODES 789: IMULI TAC,TNSIZE ;TIMES THEIR SIZE 790: MOVEM TAC,XGPNST+1 ;STORE 791: MOVE TAC,XNVNOD ;NUMBER OF VECTOR NODES 792: IMULI TAC,VNSIZE ;TIMES THEIR SIZE 793: ADDM TAC,XGPNST+1 ;ADD TO TEXT NODE SPACE, TOTAL NODE SPACE NEEDED 794: PUSHJ P,FCREQ ;REQUEST ALLOCATION FROM FC 795: POPJ P, ;LOSE. 796: MOVE TAC,XGPOST 797: CAIE TAC,1 ;EXPECTED RESPONSE IS 'ALLOCATION MADE' 798: JRST FCERRX ;UNEXPECTED RESPONSE. 799: MOVE TAC,XGPOST+1 800: MOVEM TAC,XFREBA ;SAVE ADDRESS OF THE ALLOCATION. 801: SKIPE XFTADR ;YES. WE NEED A FONT. SKIP UNLESS WE HAVE ONE. 802: JRST CPOPJ1 ;NO. MAKES THINGS EASY. 803: SETZM XGPNST+1 804: SETZM XGPNST+2 805: SETZM XGPNST+3 806: SETZM XGPNST+4 807: MOVEI TAC,2 808: MOVEM TAC,XGPNST 809: PUSHJ P,FCREQ 810: POPJ P, ;TIME OUT. ERROR CODE IS SET ALREADY. 811: MOVE TAC,XGPOST 812: CAIE TAC,2 813: JRST FCERRX ;ERROR. UNEXPECTED RESPONSE. SET EXTENDED ERROR 814: MOVE TAC,XGPOST+1 815: MOVEM TAC,XFTADR ;STOW FONT ADDRESS 816: JRST CPOPJ1 817: 818: F.LOSE: MOVEI IOS,IODTER ;USE THIS BIT FOR FC LOSSAGE 819: JRST XGPSET ;SET BIT IN IOS AND RETURN TO UUOCON. 820: 822: ; INTERPROCESSOR COMMUNICATION AT CLOCK LEVEL. HUNG TIMEOUT 823: 824: HUNG: SKIPN XGPAOK ;IS THE MAJIC CELL SET? 825: JRST HUNG1 ;NO.. IT MUST REALLY BE HUNG 826: SETZM XGPAOK 827: LDB TAC,PDVTIM 828: DPB TAC,PDVCNT ;RESET HUNG TIME.. 829: JRST CPOPJ1 ;THE XGP IS STILL THERE. 830: 831: HUNG1: SETOM XGPKIL ;KILL THE XGP 832: MOVEI IOS,IOIMPM ;TELL HIM AN ERROR. 833: PUSHJ P,XGPSET ;SET BITS 834: PUSHJ P,XERR6 ;SET ERROR CODE 835: TRNE IOS,200 ;IS USER ENABLED TO HANDLE HUNG XGP? 836: AOS (P) ;YES. DON'T GIVE HIM HUNG DEVICE THEN. 837: PUSHJ P,XDMPO1 ;SHUT OFF XGPGO, XGPBIT 838: MOVE IOS,[DEVSBB,,IOACT] 839: PUSHJ P,XGPCLR ;CLEAR IOACT AND KICK THE PDP-10 840: 841: ;PDP-10 HERE 842: ↑XGPP1: SETZM XGPP1F ;CLEAR REQUEST SET BY P2. 843: MOVEI DDB,XGPDDB ;DDB ADDRESS FOR STTIOD 844: 845: PUSHJ P,PSYNCX 846: MOVE IOS,XGPIOS 847: TLZE IOS,IOW ;WAS HE IN WAIT? 848: PUSHJ P,STTIOD ;YES, GET HIM OUT FAST 849: MOVEM IOS,XGPIOS 850: JRST XSYNCX ;UNSYNCHRONIZE AND POPJ 851: 852: 853: ; PDP-6 HERE EVERY SECOND TO MAKE SURE THAT XGP IS RUNNING. 854: ↑XGPP2: MOVEI TAC,JIFSEC 855: MOVEM TAC,XGPP2F ;BACK HERE IN 1 SECOND. 856: MOVEI TAC,0 ; 857: EXCH TAC,P2CH2 ; 858: JUMPN TAC,CPOPJ ;XGP HAS INTERRUPTED. 859: CONSZ XGP,XGPOK ;IS THE XGP STILL HAPPY? 860: POPJ P, ;NO. WELL, WHAT CAN I DO? 861: CONO PI,XGPOFF ;SNEAK IN. 862: CONO XGP,SETPI+XGPCHN+DONENB ;ASSIGN PI CHANNEL. WAIT FOR INTERRUPT. 863: PUSHJ P,XIHNG0 ;SET UP TO RESYNCHRONIZE. 864: CONO PI,XGPON ;MAKE SURE CHANNEL IS LISTENING. 865: POPJ P, ;RETURN TO CLOCK LEVEL. 867: ; User Programming for the XGP 868: COMMENT $ 869: This document reflects the state of the software as of 870: system 6.12/N. Changes may be made without prior notice and without 871: maintaining compatability with earlier systems. 872: 873: The Xerox Graphics Printer (XGP) provides a means of making 874: a hardcopy listing of virtually any drawing that can be expressed as 875: a one-bit raster. The XGP accepts as data a bit array describing 876: each scan-line that is printed. Each scan line is approximately 877: 1700 bits; scan lines are spaced at about 190 per inch along the 878: paper. A picture is built by sending successive scan lines to the 879: XGP. 880: 881: There are presently two distinct modes of operating the XGP, 882: video mode and character mode. 883: 884: Video Mode 885: 886: In video mode, 36 bit words are interpreted as video data. 887: Words are grouped together into portions of a scan-line by the use 888: of a Group Command Word (GCW). The GCW precedes the data portion of 889: the group. The GCW specifies how many words of video data are to be 890: found in this group. Also the GCW allows the video data to be 891: positioned anywhere along the scan line. The exact format of the 892: GCW is: 893: 894: BYTE (1)MARK (11)LNSKIP (12)COLSKP (6)UNUSED, DWCNT 895: 896: The fields of the GCW are interpreted as follows: 897: 898: The paper will be advanced by LNSKIP blank lines 899: before printing. LNSKIP = 1 is used for normal, 900: single spacing. LNSKIP = 0 prevents any advance to 901: the next scan line and prints on the same line as 902: the last group. 903: 904: The column register in the XGP interface will be set 905: to COLSKP before transmitting data. 906: 907: DWCNT words following the GCW will be transmitted to 908: the XGP as video data (a bit = 0 is white, 1 is 909: black). If DWCNT = 0 then there are no data words in 910: this group and the next word is another GCW. 911: 912: After data is sent, if the MARK bit is 1, the paper 913: will be marked for cutting. Paper cutting is not 914: exact so a MARK should be preceeded and followed by 915: several blank lines. 916: 917: The field labeled UNUSED has no meaning currently. 918: It should be set to zero to avoid confusion if some 919: other meaning is attached to this field. 920: 921: 922: 923: Modes 17 and 117 are used for video data. All of these 924: modes accept the format that is described above. 925: 926: In mode 17, the effective address of the OUT uuo points to a 927: standard dump mode command list. The command list specifies the 928: data to send to the XGP. Each OUT will wait until the entire 929: command list is processed before returning to the user. The paper 930: will be cut at the completion of each command list. 931: 932: Mode 117 is like mode 17 except that the OUT uuo returns to 933: the user while data is being sent to the XGP. In this mode the user 934: can overlap the input of one data block with the output of another. 935: Three data blocks are needed in this mode: one being emptied by the 936: XGP, another pending, and another being filled by the user program. 937: The first two OUT uuos will return immediately (having established 938: the current and pending output blocks). After the user fills his 939: third block and gives an OUT uuo he will be forced to wait until the 940: current block is empty (at which time the pending block becomes 941: current and the block specified in this OUT will become the new 942: pending block). When the third OUT returns, the first block will be 943: free to use. In video mode the XGP requires up to 10,000 words of 944: data per second. Care should be exercised in programming to always 945: have data ready for the XGP. 946: 947: Another requirement of mode 117 is that the command lists 948: that point to the three data blocks must be disjoint. The actual 949: requirement is that the command list for each block must be valid 950: while the block is being output. In particular, don't use the same 951: physical location in your program for more than one command list. 952: 953: In mode 117 you must do a CLOSE UUO after the last OUTPUT to 954: force the transmission of all buffers to the XGP. It is possible 955: that a user program may not be able to supply data fast enough in 956: mode 117. In this event, the output will be cut wherever the data 957: runs out. A status bit, 2000 (IOTEND), is provided which warns the 958: program that this has occurred. This bit is set only in mode 117 959: when the data runs out and no CLOSE has been done. 960: 961: $ 963: ; INTERRUPT LEVEL ROUTINES 964: ;LOCATIONS MARKED WITH *1 ARE FIRST LEVEL DISPATCH TARGETS. 965: ;LOCATIONS MARKED WITH *2 ARE SECOND LEVEL DISPATCH TARGETS. 966: ;LOCATIONS MARKED WITH *4 ARE DISPATCH TARGETS AT PI CHANNEL 4. (TEXT MODE) 967: 968: 969: SDISP1: MOVEM TAC,XDISP1 ;JSP TAC,SDISP1 TO SET NEW DISPATCH ADDRESS 970: POPJ P, ;JSR XGPSAV MUST HAVE BEEN DONE ALREADY. 971: 972: ↑XGPINT: 973: CONO XGP,SETALL≠PAPER ;CLEAR DONE. SET DONE ENABLE, ETC. 974: SOSLE XFLAPC ;DECREMENT FLAPPER COUNT 975: JRST XGINT1 976: MOVEM TAC,XGPTMP ;SAVE TAC 977: MOVEI TAC,=100 978: MOVEM TAC,XFLAPC ;SET UP FLAPPER COUNT 979: MOVE TAC,XFLAPA ;WORD 1 980: EXCH TAC1,XFLAPB ;WORD 2 981: LSHC TAC,1 ;SHIFT THEM BOTH 982: MOVEM TAC,XFLAPA ;STORE 1 983: EXCH TAC1,XFLAPB ;AND 2 984: TRNE TAC,1000 ;TIME TO FLAP? 985: DATAO 500,[20,,0] ;YES: FLAP THE FLAPPER 986: MOVE TAC,XGPTMP 987: 988: XGINT1: SOSE XCUTQ ;TIME TO CUT NOW? 989: JRST XGINT2 ;NO. 990: CONO XGP,SETCON!CUTNOW 991: SOS XCUTBP 992: MOVEM TAC,XGPTMP 993: MOVE TAC,[XCUTQ+1,,XCUTQ] 994: BLT TAC,XCUTQ+=46 ;MOVE QUEUE NODES DOWN 995: MOVE TAC,XGPTMP 996: 997: XGINT2: CONSZ XGP,XGPOK ;IS THE XGP STILL ALIVE? 998: JRST XIHUNG ;INTERFACE REPORTS XGP LOSSAGE. 999: SETOM XGPAOK ;TELL PDP-10 THAT WE STILL SEE INTERRUPTS. 1000: CONO XGP,SETX 1001: CONO XGP,SETCON!SWPBUF 1002: CONO XGP,SETX 1003: JRST @XDISP1 ;DISPATCH LEVEL1 1004: 1005: 1006: ;*1 HERE TO ESTABLISH XGP SYNCHRONIZATION. 1007: XGSYNC: SETZM XGPIGO 1008: SOSLE XYNCNT ;COUNT BUFFER SWITCHES. 1009: JEN @XGPCHL ;DISMISS INTERRUPT 1010: JSR XGPSAV 1011: MOVEI TAC,=4096 1012: MOVEM TAC,XYNCNT 1013: XGIDLE: JSP TAC,SDISP1 ;WE ARE NOW IN SYNC. -SET TO IDLE 1014: 1015: ;*1 HERE TO MAINTAIN SYNCHRONIZATION. 1016: MOVEM TAC,XGPTMP 1017: MOVE TAC,XGPBIT 1018: JUMPN TAC,XGSYGO ;IS THE PDP-10 REQUESTING ACTION? 1019: MOVE TAC,XGPTMP 1020: JEN @XGPCHL ;KEEP IDLING. 1021: 1022: XGSYGO: MOVE TAC,XGPTMP 1023: JSR XGPSAV 1024: MOVEI TAC,=600 ;SET UP COUNT 1025: MOVEM TAC,XGPCNT 1026: JSP TAC,SDISP1 ;SET NEW DISPATCH AND DISMISS 1027: 1028: ;*1 RUN THE PAPER FOR 600 LINES UNTIL IT'S GOING FAST ENOUGH. 1029: CONO XGP,SETALL ;START THE PAPER. 1030: SOSLE XGPCNT 1031: JEN @XGPCHL 1032: JSR XGPSAV 1033: MOVSI IOS,XPAPER 1034: PUSHJ P,PSYNCX ;SET A BIT IN IOS, 1035: IORM IOS,XGPIOS 1036: MOVE IOS,XGPBIT ;THIS CELL HOLDS THE PDP-10'S DESIRES. 1037: JUMPE IOS,.+2 1038: PAPOON: SETOM XGPP1F ;TELL PDP-10 TO LOOK. 1039: MOVE IOS,[DEVSBB,,IOACT] 1040: ANDCAM IOS,XGPIOS 1041: PUSHJ P,XSYNCX 1042: JSP TAC,SDISP1 ;SET NEW DISPATCH. 1043: 1044: ;*1 HERE WE WAIT UNTIL PDP-10 SAYS DATAREADY 1045: CONO XGP,SETALL 1046: JSR XGPSAV 1047: MOVE IOS,XGPKIL 1048: JUMPN IOS,XMITFF ;JUMP IF PDP-10 IS KILLING THIS TRANSFER. 1049: MOVE IOS,XGPGO 1050: JUMPE IOS,CPOPJ 1051: JSP TAC,SDISP1 ;SET NEW DISPATCH AND DISMISS. 1052: 1053: ;*1 HERE FOR INTERRUPT AND WE WANT TO SEND DATA. 1054: XMITIN: ;DATA TRANSMIT INTERRUPT. 1055: SETOM XGPIGO ;I-LEVEL DATA TRANSFER IN PROGRESS. 1056: CONO XGP,SETALL ;CLEAR DONE, SET DONE ENABLE,PI, AND PAPER 1057: JSR XGPSAV ;SAVE ALL AC'S FOR I LEVEL CODE. 1058: MOVE TAC,XGPKIL ;LOOK TO SEE IF PDP-10 HAS TIMED OUT 1059: JUMPN TAC,XMITFF ;PDP-10 THINKS WE'RE HUNG. STOP QUICK. 1060: PUSHJ P,@XDISP2 ;DISPATCH ACCORDING TO DATA MODE. 1061: POPJ P, ;NORMAL RETURN. DISMISS. 1062: JRST XMITFG ;END OF TRANSFER. 1063: XMITFF: PUSHJ P,QCUT ;FORCED END. CUT PAPER. 1064: XMITFG: MOVEI PID,P2PID ;MAKE SURE PID IS RIGHT. 1065: PUSHJ P,PSYNCX 1066: MOVE IOS,[DEVSBB,,IOACT] 1067: ANDCAM IOS,XGPIOS 1068: SETZM XGPBIT ;CLEAR XGPBIT SO IF THE 10 HANGS, WE DONT 1069: SETZM XGPIGO ;I-LEVEL DATA XFER IDLE. 1070: SETOM XGPP1F ;TELL PDP-10 THAT DATA XFER COMPLETE 1071: ;TRANSMISSION DONE. COUNT AS THE PAPER RUNS OUT 5000 LINES. 1072: ;CUT THE PAPER EVERY 2200 LINES (11 INCHES) SO THE STACKER WILL NOT HAVE 1073: ;20 INCH PAGES TO CONTEND WITH. 1074: MOVEI TAC,=16 1075: MOVEM TAC,XGPCNY ;16 TIMES 263 LINES 1076: XMITD1: PUSHJ P,XSYNCX ;RELEASE INTERLOCK 1077: MOVEI TAC,=275 1078: MOVEM TAC,XGPCNT 1079: JSP TAC,SDISP1 1080: 1081: ;*1 HERE AFTER COMMAND LIST HAS RUN OUT. COUNT PAPER FEED. 1082: SOSLE XGPCNT ;COUNT PAPER FEED 1083: JEN @XGPCHL 1084: JSR XGPSAV 1085: PUSHJ P,PSYNCX 1086: SOSLE TAC,XGPCNY 1087: TRNN TAC,7 1088: PUSHJ P,QCUT0 ;QUEUE CUT (MARK PAPER TOO SO WE DON'T FORGET) 1089: JUMPG TAC,XMITD1 ;TIME TO STOP COUNTING THE PAPER? 1090: MOVSI IOS,XPAPER ;WE WANT TO CLEAR THIS. 1091: MOVE TAC,XGPBIT ;DOES PDP-10 HAVE THIS BIT ON? 1092: JUMPN TAC,PAPOON ;YES. THEN DON'T CLEAR IT! 1093: ANDCAM IOS,XGPIOS 1094: PUSHJ P,XSYNCX 1095: JRST XGIDLE ;SET IDLE DISPATCH. 1097: ; HERE FOR 'NOT XGPOK' ALSO, QUEUE CUT MARKS. 1098: XIHUNG: JSR XGPSAV 1099: MOVE TAC,XGPBIT ;ARE WE SUPPOSED TO BE DOING SOMETHING? 1100: MOVSI IOS,XPAPER ; 1101: TDNN IOS,XGPIOS ; 1102: JUMPE TAC,XIHNG0 ;WE HAVE BEEN IDLE. 1103: PUSHJ P,PSYNCX 1104: SETZM XGPBIT ;WE ARE GOING TO BE IDLE. 1105: MOVEI TAC,IODERR ;SET ERROR FLAG. 1106: IORM TAC,XGPIOS 1107: ANDCAB IOS,XGPIOS ;TURN OFF XPAPER IN XGPIOS. 1108: PUSHJ P,XERR6 ;XGP IS NOT OK. 1109: SETOM XGPP1F ;TELL THE PDP-10 WE LOST. 1110: PUSHJ P,XSYNCX 1111: XIHNG0: MOVEI TAC,=4096 1112: MOVEM TAC,XYNCNT 1113: MOVEI TAC,XGSYNC ;SET DISPATCH TO RESYNCHRONIZE XGP. 1114: MOVEM TAC,XDISP1 ; 1115: MOVEM TAC,XGPIGO ;NOT IN DATA PORTION OF I-LEVEL 1116: POPJ P, ;(POSITIVE DENOTES UNHAPPY!) 1117: 1118: QCUT0: CONO XGP,SETCON!MARKIT ;MARK PAPER TOO (SO WE DON'T FORGET) 1119: QCUT: PUSH P,TAC 1120: PUSH P,TAC1 1121: MOVEI TAC,XCUTQ ;GET THE ADDRESS OF THE CUT QUEUE 1122: MOVEI TAC1,=4650 ;THIS IS THE CUT DELAY (TWIDDLE) 1123: QCUT1: CAILE TAC,@XCUTBP ;ARE WE STILL IN THE LIST? 1124: JRST QCUT2 ;NO. (DONE) 1125: SUB TAC1,(TAC) ;DECREMENT 1126: AOJA TAC,QCUT1 ;LOOK FOR MORE 1127: 1128: QCUT2: CAILE TAC1,=100 ;CUT TOO SMALL? 1129: IDPB TAC1,XCUTBP ;NO. ADD IT TO THE QUEUE 1130: POP P,TAC1 1131: JRST TPOPJ ;RESTORE TAC AND RETURN 1132: 1134: ; MODE 17 I-LEVEL 1135: ;XGPIWD HAS ABSOLUTE AOBJN POINTER 1136: ;XGPMDP HAS PROG,,REL ADDRESS OF THIS IOWD. 1137: ;XGPROG HAS RELOCATION OF CURRENT JOB. 1138: 1139: ;*2 HERE AT FIRST LINE OF TRANSFER, OR FIRST LINE OF PAGE 1140: XDI: SETZM XSCNLN ;COUNT SCAN-LINES. 1141: MOVEI TAC,XDILIN 1142: MOVEM TAC,XDISP2 1143: JRST XDILIN 1144: 1145: XDI4: JSP AC3,XADV ;HERE TO ADVANCE TO NEXT COMMAND 1146: 1147: ;*2 HERE WE KNOW THAT WE ARE ON A NEW SCAN LINE. 1148: XDILIN: MOVE TAC,XGPIWD ;GET CURRENT IOWD 1149: JUMPGE TAC,XDI4 ;JUMP IF IT HAS RUN OUT. 1150: XDI0: MOVE DAT,(TAC) ;GET GROUP COMMAND WORD. 1151: MOVEM DAT,XGPGCW ;SAVE IT. 1152: LDB DAT,LNSKIP ;GET THE LINE SKIP COUNT 1153: ADDM DAT,XSCNLN ;COUNT SCAN-LINES 1154: SOJLE DAT,XDI1 ;JUMP IF THERE ARE NO LINES TO SKIP. 1155: MOVEM DAT,XGPCNT ;SAVE COUNT 1156: JSR XDISP2 ;SET DISPATCH AND DISMISS INTERRUPT. 1157: 1158: ;*2 HERE TO SKIP LINES FOR A WHILE. 1159: SOSLE XGPCNT ;DECREMENT COUNT OF LINES TO SKIP. 1160: POPJ P, ;DISMISS 1161: MOVEI DAT,XDILIN ;RESET INTERRUPT DISPATCH 1162: MOVEM DAT,XDISP2 1163: MOVE TAC,XGPIWD ;REFORM AC'S. 1164: XDI1: LDB DAT,COLSKP ;HOW FAR TO SKIP? 1165: CONO XGP,SETX(DAT) ;SET X POSITION IN XGP 1166: AOBJN TAC,.+1 ;ADVANCE AOBJN POINTER. 1167: MOVEM TAC,XGPIWD 1168: XDI1A: HLRO TAC1,TAC ;GET -(COUNT REMAINING) 1169: MOVM TAC1,TAC1 ;GET (COUNT REMAINING) 1170: LDB AC1,DWCNT ;GET DATA COUNT FROM USER 1171: MOVEI DDB,(AC1) ;A COPY. 1172: CAILE AC1,(TAC1) ;DATA COUNT SHOULD BE SMALLER 1173: MOVEI AC1,(TAC1) ;SET TO MAX ALLOWED COUNT. 1174: SUBI DDB,(AC1) ;REMAINDER AFTER OVERFLO. 1175: DPB DDB,DWCNT ;SAVE REMAINDER. 1176: MOVEI TAC1,(AC1) ;AND THIS IS HOW WE FIX IOWD 1177: HRLI TAC1,(TAC1) 1178: ADDM TAC1,XGPIWD ;FIX AOBJN POINTER. 1179: JUMPE AC1,XDI3 ;POSSIBLE ZERO DATA WORDS. 1180: MOVNI AC1,(AC1) ;AND FORM AOBJN POINTER IN TAC 1181: HRLI TAC,(AC1) 1182: MOVE AC1,TAC ;AOBJN POINTER IN AC1 1183: MOVEM P,XGPTMP ;SAVE PUSHDOWN POINTER 1184: MOVSI 13,XDI2 ;SOURCE,,DESTINATION 1185: BLT 13,13 ;STUFF CODE IN AC'S 1186: JRST XDI2A ;JUMP INTO THE START 1187: ;RUN THE INNER LOOP IN THE AC'S. 1188: 1189: XDI2: 1190: PHASE 0 ;CODE ASSUMES AC1>13 1191: XDI2A:: MOVE AC3,(AC1) ;0 GET 36 BITS OF VIDEO DATA. 1192: MOVEI AC2,0 ;1 1193: LSHC AC2,=16 ;2 1194: DATAO XGP,AC2 ;3 SEND 16 BITS 1195: MOVEI AC2,0 ;4 1196: LSHC AC2,=16 ;5 1197: DATAO XGP,AC2 ;6 ANOTHER 16 1198: LSHC AC2,=16 ;7 1199: IORI AC2,200004 ;10 OR BITS FOR SPECIAL MODE, WIDTH 4. 1200: DATAO XGP,AC2 ;11 SEND DATA 1201: AOBJN AC1,XDI2A ;12 LOOP. 1202: JRST XDI2B ;13 1203: DEPHASE 1204: 1205: XDI2B: MOVE P,XGPTMP ;RESTORE P 1206: MOVEI PID,P2PID ;RESTORE PID 1207: LDB TAC,DWCNT 1208: JUMPE TAC,XDI3 ;JUMP IF NO IOWD OVERFLOW. 1209: JSP AC3,XADV ;ADVANCE TO NEW IOWD. 1210: MOVE TAC,XGPIWD ;GET A NEW AOBJN POINTER. 1211: JRST XDI1A ;PROCESS MORE VIDEO. 1212: 1213: XDI3: SKIPGE XGPGCW 1214: PUSHJ P,XDICUT ;MAKE PAPER GET CUT 1215: SKIPL TAC,XGPIWD ;PEEKING AT NEXT GCW 1216: POPJ P, ;IOWD RAN OUT-NO NEXT GCW 1217: LDB DAT,[POINT 11,(TAC),11] ;GET THE LINE SKIP FROM NEXT GCW 1218: JUMPE DAT,XDI0 ;IF COUNT=0, DO MORE ON THIS LINE. 1219: POPJ P, ;RETURN. DONE WITH LINE. 1220: 1221: XDICUT: PUSHJ P,QCUT ;QUEUE A PAPER CUT 1222: MOVEI TAC,XDI 1223: MOVEM TAC,XDISP2 1224: MOVE TAC,XSCNLN 1225: CAIL TAC,=2000 1226: CAILE TAC,=2200 1227: POPJ P, ;PAGE SIZE IS UNUSUAL 1228: MOVEI TAC,1 1229: IORM TAC,XFLAPB ;FLAP THE FLAPPER (LATER) 1230: POPJ P, ; 1232: ; XADV ADVANCE IOWD AT I-LEVEL 1233: XADV: SKIPE TAC1,XGPBIG ;PART OF A BIG TRANSFER LEFT? 1234: JRST XADV2 ;YES. SKIP SOME CODE 1235: MOVE PROG,XGPROG ;HERE THE IOWD RAN OUT. 1236: SKIPN XGPMDP ;IS THERE A COMMAND IN PROGRESS? 1237: JRST XADV3 ;NO. GET THE NEW COMMAND IF ANY. 1238: AOS TAC1,XGPMDP ;GET RELATIVE POINTER AND INCREMENT 1239: XADV1: HRLI TAC1,PROG 1240: MOVEM TAC1,XGPMDP 1241: MOVE TAC1,@TAC1 1242: JUMPE TAC1,XADV3 ;COMMAND HAS RUN OUT. SEE IF ANOTHER 1243: TLNN TAC1,-1 1244: JRST XADV1 ;FOLLOW JUMPS 1245: ADDI TAC1,1(PROG) ;MAKE IT ABSOLUTE AOBJN WORD. 1246: MOVEM TAC1,XGPIWD ;STORE AOBJN WORD. 1247: JUMPL TAC1,(AC3) ;RETURN IF SMALL AOBJN WORD. 1248: TLC TAC1,400000 ;MAKE COUNT 400000 SMALLER. 1249: MOVEM TAC1,XGPIWD ;SAVE THE SMALL PART TO DO FIRST 1250: HLRE PROG,TAC1 ;GET - COUNT OF FIRST PART 1251: SUB TAC1,PROG ;CALC FIRST ADDR OF SECOND PART 1252: HRLI TAC1,400000 ;THIS IS HOW MANY WORDS 1253: MOVEM TAC1,XGPBIG ;FLAG MORE TO DO 1254: JRST (AC3) 1255: 1256: XADV2: MOVEM TAC1,XGPIWD 1257: SETZM XGPBIG ;ONLY ONCE 1258: JRST (AC3) 1259: 1260: XADV3: MOVE TAC1,XGPNXC ;SWAP ZERO FOR THE NEW COMMAND 1261: JUMPE TAC1,XADV4 ;FINISHED IF NO NEW COMMAND 1262: SETZM XGPNXC ;CLEAR NEW COMMAND 1263: SETOM XGPP1F ;KICK THE PDP-10 1264: JRST XADV1 ;AND PROCESS THE NEW COMMAND 1265: 1266: XADV4: SETZM XGPMDP ;NO MAJOR COMMAND 1267: AOS (P) ;WE SHALL STOP XGP ON RETURN 1268: PUSHJ P,PSYNCX 1269: MOVE IOS,XGPIOS 1270: TRNE IOS,100 ;OVERLAPPED MODE? 1271: TLNE IOS,IOEND ;YES. CLOSE UUO DONE YET? 1272: JRST XSYNCX ;NOT OVERLAPPED OR CLOSE DONE. 1273: ;RELEASE SYNCHRONIZER AND STOP XGP. 1274: MOVEI IOS,IOTEND ;OVERLAPPED MODE, END OF DATA AND NO CLOSE. 1275: IORM IOS,XGPIOS ;TURN ON ERROR BIT 1276: JRST XSYNCX ;RELEASE SYNCHRONIZER. 1278: ; BUFFER ADVANCE AT I-LEVEL 1279: ;BFOSET IS CALLED AT THE BEGINNING OF EACH SCAN LINE TO CALCULATE AN 1280: ;AOBJN POINTER TO THE SYSTEM BUFFER. POINTER IS RETURNED IN TAC. 1281: 1282: ;BFNSET IS CALLED AT THE END OF EACH SCAN LINE TO ADJUST THE BUFFER COUNTS 1283: ;AND THINGS. ARGUMENT IS TAC, THE REMAINDER OF THE AOBJN POINTER. 1284: 1285: ;IF THE AOBJN POINTER RUNS OUT IN THE MIDDLE OF A SCAN LINE IT MAY BE DUE 1286: ;TO EITHER WRAP AROUND OR LACK OF DATA. CALL BFNSET TO REFORM PARAMETERS 1287: ;FOLLOWED BY BFOSET TO GET A NEW POINTER. IN CASES OF NO DATA LEFT IN THE 1288: ;BUFFER, TAC WILL COME BACK AS A POSITIVE QUANTITY. 1289: 1290: BFOSET: MOVN AC1,XBFCNT ;GET -DATA COUNT IN BUFFER. 1291: MOVE TAC,XTAKE ;GET TAKE POINTER 1292: SUB TAC,XIBFND ;MAKE -COUNT FROM TAKE TO THE END. 1293: CAMGE AC1,TAC ;SKIP IF DATA DOESN'T WRAP. 1294: MOVE AC1,TAC ;WRAP AROUND. DO THE REST LATER. 1295: MOVE TAC,XTAKE 1296: HRLI TAC,(AC1) ;FORM AOBJN POINTER IN TAC 1297: MOVEM TAC,XGPIWD ;SAVE HERE TOO. 1298: JRST (AC3) ;RETURN. 1299: 1300: BFNSET: MOVE AC1,XTAKE 1301: SUBI AC1,(TAC) ;COMPUTE -COUNT OF WORDS USED UP. 1302: HLLI TAC, ;CLEAR TAC LEFT. 1303: CAML TAC,XIBFND ;DID WE WRAP AROUND? 1304: MOVE TAC,XIBUF ;YES. RESET TAKER 1305: MOVEM TAC,XTAKE 1306: PUSHJ P,PSYNCX 1307: ADDB AC1,XBFCNT ;DECREASE COUNT OF SPACE IN USE. 1308: CAMG AC1,XGPWSZ ;IS IT PROPER TO REACTIVATE PDP-10? 1309: SKIPN XGPWSZ ;YES. SPECIAL FLAG FOR CLOSE? 1310: JRST BFNST1 ;NOT TIME YET, OR CLOSE IN PROGRESS 1311: MOVSI IOS,DEVSBB 1312: ANDCAM IOS,XGPIOS ;SYSTEM BUFFER NOT BUSY. 1313: SETOM XGPWSZ ;DON'T REACTIVATE AGAIN SOON. 1314: SETOM XGPP1F ;ACTIVATE PDP-10 1315: BFNST1: PUSHJ P,XSYNCX 1316: JRST (AC3) 1318: ; Character Mode for the XGP 1319: COMMENT $ 1320: 1321: Modes 0 and 13 are the character modes in the XGP. In these 1322: modes, 36 bit words are interpreted as five 7-bit bytes. There is 1323: no fixed mapping between byte values and particular graphic symbols. 1324: The graphic symbol for any byte is defined by the current font in 1325: use. Certain byte values have special meanings consistient with 1326: ASCII and one byte value, octal 177, is used as an escape which 1327: gives the bytes that follow a special meaning. 1328: 1329: Character mode permits vectors and multiple active text 1330: lines. 1331: 1332: Character mode interprets 7-bit bytes taken from the user's 1333: buffer as follows: 1334: 1335: Byte Usual meaning Escape significance 1336: 1337: 0 Null - byte is ignored Normal 1338: 1 Normal XGP ESCAPE 1 1339: 2 Normal XGP ESCAPE 2 1340: 3 Normal XGP ESCAPE 3 1341: 4 Normal XGP ESCAPE 4 1342: 5-10 Normal Reserved 1343: 11 TAB Normal 1344: 12 LF Normal 1345: 13 Normal Reserved 1346: 14 FF Normal 1347: 15 CR Normal 1348: 16-37 Normal Reserved 1349: 40-176 Normal Normal 1350: 177 ESCAPE Normal 1351: 1352: Normal means the definition of this byte in the current font will be 1353: printed. If this byte is undefined in the current font, it will be 1354: ignored. 1355: 1356: ESCAPE causes the next byte to have an alternate meaning selected 1357: from the column "Escape significance". 1358: 1359: TAB produces a column select to the column which is at least the 1360: width of a blank to the right of the current column position, and 1361: some multiple of 8 blank widths to the right of the left margin. 1362: 1363: LF activates the current text line. The current text will be queued 1364: to printed. The default Y position of text will be advanced by the 1365: number of scanlines it takes to draw this line, plus the number of 1366: lines specified by the interline space argument to the margin set 1367: MTAPE. This default Y position will be used for the next text line 1368: (unless changed by a vector command or ESCAPE-3. 1369: 1370: FF, like LF, activates the text. In addition, FF causes a page 1371: eject after the current text line is printed. FF also sets the 1372: defalut Y position to the first line below the top of page margin on 1373: the new page. 1374: 1375: CR causes a column select to the current left margin to be 1376: generated. 1377: 1378: XGP ESCAPE 1 ('177&'001) causes the next 7 bits to be read as a 1379: special operation code. The following codes are implemented: 1380: 1381: 0-17 Font select. 1382: The code, 0 to 17 is taken as the font identification 1383: number of the font to use. 1384: 1385: 20-37 Reserved for future use. 1386: 1387: 40 XGP Column Selector 1388: The next 14 bits are taken modulo 4096 as the 1389: x-position to print at next. (The intention is to 1390: allow arbitrary width spaces for text justification.) 1391: 1392: 41 XGP Underscore 1393: The next byte (in two's complement) is the relative 1394: scan line on which the underscore is to occur, where 1395: 0 represents the baseline of the text, negative 1396: values represent lines above the baseline and 1397: positive values lines below it. The next 14 bits 1398: (modulo 4096) specify the length of the underscore. 1399: (If the underscore command is the first thing on a 1400: line, the baseline will be set to the baseline of the 1401: current font.) 1402: 1403: 42 Line space. 1404: This does a line feed and then takes the byte as the 1405: number of blank lines to insert before the next line. 1406: 1407: 43 Base-line adjust. 1408: The next 7 bits are taken in two's complement as the 1409: base-line adjustment to the current font. The 1410: adjustment sticks until reset by another adjust 1411: command or a font select. The intention is to allow a 1412: font to be used for subscripts and superscripts. 1413: (Increment baseline for superscript, decrement for 1414: subscript). 1415: 1416: 44 Print the paper page number. 1417: The paper page number is set to 1 by a form feed. It 1418: is incremented each time the paper is cut. The 1419: decimal value of this count is printed. 1420: 1421: 45 Accept heading text. 1422: The next byte is a count of bytes to follow. Those 1423: bytes will be read into the heading line. When that 1424: count is exhausted, the heading line will be printed. 1425: If a line feed or line space command is given that 1426: would cause text to be printed below the current text 1427: area, a form feed is inserted by the XGP and if a 1428: heading is defined, it will be printed. 1429: 1430: 46 Start Underline. 1431: Set the left end of an underline. See Stop Underline. 1432: 1433: 47 Stop Underline. 1434: The next byte is the scan line on which to write the 1435: underline (same as XGP Underscore). The extent of 1436: the underscore is defined by this command and Start 1437: Underline. If this command is not preceded by a Start 1438: Underline, the results will be unpredictable. Beware 1439: of column selects. No underline will happen until 1440: this command is given. 1441: 1442: 50 Set Inter-Character Space. The next byte is taken as 1443: the column increment to add after each character. 1444: Note: this takes a major amount of extra compuation 1445: in the Stanford implementation. Use of this feature 1446: may produce documents that cannot be listed. 1447: 1448: XGP ESCAPE 2 ('177&'002) causes the next 7 bits to be taken as the 1449: column increment. This quantity is signed: 0-77 are positive 1450: increments 100 to 177 are negative increments (100 → -100, 177 → -1). 1451: 1452: XGP ESCAPE 3 ('177&'003) causes the next 2 bytes to be taken as the 1453: scan line number on which to start this text line. Scan line 0 is 1454: the first scan line on the page (immediately following the cut). 1455: The topmost scanline of the present text line will be placed on the 1456: scan line indicated in this command. (If there is no current text 1457: line, the next text line will be put there.) 1458: 1459: XGP ESCAPE 4 ('177&'004). This escape is used to specify a vector. 1460: It is followed by 11 bytes describing the vector: 1461: 1462: 2 bytes Y0 Scan line number of first line of vector. 1463: 2 bytes X0 Column position of left edge of first line 1464: of the vector. 1465: 3 bytes DX Delta X. 1 bit of sign; 11 bits of integer; 1466: 9 bits of fraction. 1467: 2 bytes N The number of scan lines on which this vector 1468: is visible. 1469: 2 bytes W The column width of each scan-line. 1470: 1471: The XGP service must be presented with vectors sorted by 1472: ascendending values of Y0. If the vectors are not sorted, the 1473: output will be wrong. 1474: 1475: The escape significance of codes 5 through 10, 13, and 16 through 1476: 37 is not defined at the present time but reserved for future use. 1477: 1478: $ 1480: ; MODE 0 COMMENTS ABOUT INTERNAL STRUCTURE. 1481: COMMENT $ 1482: The code to process text in mode 0 is broken up into two 1483: phases. There is the 'line assembly' phase which occurs once per 1484: text line and the 'scan' phase which occurs once per generated 1485: scanline. 1486: 1487: The 'scan' phase is intended to be quite simple. The inner 1488: loop for this phase is at SCANX, and runs in the accumulators on the 1489: PDP-6. The scan phase excutes commands from a buffer that was 1490: generated during the line assembly. The buffer has the following 1491: format: 1492: 1493: XLINE: 1494: CAIL AC1,MIN ;←----(UCHN - MAJOR COMMAND) 1495: CAIL AC1,MAX 1496: L1: JRST L2 ;JUMP TO NEXT MC 1497: MOVEI TAC,(AC1) 1498: SUBI TAC,@.-4 1499: ROT TAC,-1 1500: JSP AC2,.+2 1501: 0,,L8 ;POINT TO NEXT MINOR GROUP 1502: ;USED BY JRST @(AC2) 1503: 1504: ;THIS GROUP MAY BE REPEATED FOR EVERY EXPLICIT COLUMN SELECT.-------------⊗ 1505: CONO XGP,140000+COLUMN ;COLUMN SELECT FOR MINOR GROUP | 1506: JSP AC3,SCAN ;CALL ROUTINE TO TRANSMIT DATA | 1507: -N,,.+1 ;←----(DSER - CURRENT AOBJN) | 1508: BLOCK N ;DATA TO SEND | 1509: ;-------------------------------------------------------------------------⊗ 1510: 1511: JRST @(AC2) 1512: L2: CAIL AC1,MIN ;SECOND MAJOR COMMAND 1513: CAIL AC1,MAX 1514: L3: JRST L6 ;JUMP TO NEXT MC 1515: MOVEI TAC,(AC1) 1516: SUBI TAC,@.-4 1517: ROT TAC,-1 1518: JSP AC2,.+2 1519: 0,,L5 ;POINT TO NEXT MINOR GROUP 1520: CONO XGP, 1521: JSP AC3,SCAN 1522: -N,,.+1 1523: BLOCK N 1524: JRST @(AC2) 1525: L4: JSP AC2,.+2 1526: 0,,L1 ;POINT TO NEXT MINOR GROUP 1527: .... 1528: JRST @(AC2) 1529: L5: JSP AC2,.+2 1530: 0,,L3 1531: ... 1532: JRST @(AC2) 1533: L6: CAIL AC1,MIN 1534: CAIL AC1,MAX 1535: L7: JRST CPOPJ 1536: MOVEI TAC,(AC1) 1537: SUBI TAC,@.-4 1538: ROT TAC,-1 1539: JSP AC2,.+2 1540: 0,,L7 1541: ... 1542: JRST @(AC2) 1543: L8: JSP AC2,.+2 1544: 0,,L4 1545: ... 1546: JRST @(AC2) 1547: 1548: In an attempt to provide job security, the author made this so 1549: complicated that no one else can understand it. That he failed is 1550: evident: he doesn't understand it either. 1551: 1552: Pending Queue and Active Lists. 1553: The line compiler processes text and compiles text nodes and vector 1554: nodes. These nodes are queued on a single list. The Scan Phase 1555: processes these queues and activates nodes at the appropriate time. 1556: There are 4 kinds of nodes; narrow vectors, wide vectors, text, and 1557: page mark. Each of these node types (except the page mark node) is 1558: linked onto a separate list for the per-scanline processing. The 1559: page mark node causes all active nodes to be cancelled. 1560: 1561: Narrow Vector Wide Vector Text Page 1562: 1563: 0 Link Link Link Link 1564: 1 Y0 Y0 Y0 Y0 1565: 2 X0,,n X0,,n -n 0 1566: 3 Width Width Link-2 -1 1567: 4 DX DX Unspecified EOFFLG 1568: 1569: Y0 in all cases denotes the scan line number on which the node 1570: becomes active. 'n' denotes the number of lines on which the node is 1571: active. The nodes are all queued on a single pending list. The 1572: nodes are distinguished by word 2 (negative means text node) and by 1573: word 3 (negative means page node, narrow and wide are distinguished 1574: by the values of Width). 1575: 1576: Vector nodes are 5 words. Text nodes are 64. words. 1577: 1578: The first interrupt to transmit data activates XCIBEG in channel 2. 1579: This routine arranges for XCPINI, the compiler initialization, to be 1580: run in channel 4, and it actiavates an interrupt in channel 4. 1581: XCIBEG also initializes the pending queue and the active lists to 1582: empty. 1583: 1584: Subsequent channel 2 interrupts will inspect the pending queue and 1585: activate the first node on that queue when ready. Nodes that have 1586: been activated are linked onto one of the three active lists. (There 1587: is no list for page nodes, since only one can be active). After 1588: activating any pending nodes that have become active, the active 1589: lists are processed. As each active node is processed, its 1590: activation counter is decremented. When the activation counter 1591: reaches 0, the node is deactivated by delinking it from the active 1592: list and linking it to the appropriate free list. Whenever additions 1593: to the free lists are made, the compiler is activated. 1594: 1595: Page mark nodes are treated specially. When such a node is 1596: activated the paper is marked for cutting. Since there should be 1597: nothing active across the cut mark, all active nodes are deactivated 1598: without further processing and returned to free storage. If the cell 1599: EOFFLG in the page mark node contains a non-negative quantity, that 1600: signifies that the end of text processing has been reached. Channel 1601: 2 will exit to the co-routines that feed paper and prepare for 1602: another transfer. 1603: 1604: The active vector nodes are processed quite simply. X←X+dX. The 1605: vector is drawn at the new X position for the specified width. The 1606: only peculiarity about vectors is the separation, by width, into 1607: narrow and wide vectors. This separation is necessary because wide 1608: vectors take longer to process in the XGP interface and no further 1609: interface commands may be issued until the processing of the wide 1610: vector stops. 1611: 1612: Active text nodes are processed by loading AC1 with the scanline 1613: number and executing the subroutine that was compiled into the text 1614: node. The text subroutine is called with a PUSHJ P, instruction. 1615: The first location of the subroutine is the fourth word of the node. 1616: 1617: The compiler is initialized at XCPINI. The address of XCPINI is set 1618: into X2DISP, the compiler co-routine restart address, by XCIBEG. The 1619: initialization builds the free vector node list and the free text 1620: node list. The initial column position, Y position, and font are 1621: set here. The compilation of each line is started at XCI. When the 1622: first printing character (or underscore command) is compiled, a 1623: text node is taken from the free list and initialized. PDP-6 1624: instructions are compiled into the text node. If there are more 1625: instructions than will fit, another text node is gotten from the 1626: free list and linked appropriately to the existing nodes. If at any 1627: point there are no text nodes free, the compiler sets an appropriate 1628: co-routine restart address and dismisses until activated by channel 1629: 2. When a vertical spacing character is encountered, the line 1630: compilation is terminated. The text node is linked to the end of the 1631: pending queue. From the particular line spacing character, the 1632: vertical position of the next line is calculated. (Form feed will 1633: cause a page mark node to be generated and queued, as will line feed 1634: off the bottom of the page body.) After queuing the text node, the 1635: compiler starts on the next text line. 1636: 1637: $ 1639: ; MODE 0 CHANNEL 2 INTERRUPTS 1640: ;*2 HERE ON FIRST INTERRUPT TO SEND DATA. 1641: XCIBEG: MOVEI TAC,XCPINI ;INITIAL DISPATCH FOR THE COMPILER 1642: MOVEM TAC,X2DISP ;SET FOR CHANNEL 4. 1643: SETZM XPENDH ;NO PENDING LIST. 1644: MOVEI TAC,XPENDH 1645: MOVEM TAC,XPENDT ;TAIL OF THE PENDING LIST POINTS TO HEAD. 1646: SETZM XASVLH ;NO ACTIVE LISTS. 1647: SETZM XALVLH 1648: SETZM XATLH 1649: SETOM XSCNLN ;MORE INITIALIZATION 1650: PUSHJ P,QCUT ;MAKE A CUT HERE. 1651: CONO PI,1B24!<1⊗<7-XGPC2N>> ;MAKE AN INTERRUPT ON CH4 1652: MOVE TAC,[JRST P2CH4S] 1653: MOVEM TAC,P2CH4E ;CLOBBER CHANNEL 4 EXIT ROUTINES. 1654: JSR XDISP2 ;SET DISPATCH FOR ALL OTHER INTERRUPTS. 1655: 1656: ;*2 HERE ON NORMAL, CH 2 DATA TRANSFER INTERRUPT. 1657: XCW: SETZM XACT4 ;NO NEED TO KICK CH4 YET. 1658: AOS AC1,XSCNLN ;INCREMENT PAGE POSITION. 1659: XCW1: SKIPE AC2,XPENDH ;ANY PENDING NODES? 1660: CAMGE AC1,1(AC2) ;YES. TIME YET? 1661: JRST XCW3 ;NONE PENDING OR NOT YET. 1662: CAMG AC1,1(AC2) ;DID WE MISS IT? 1663: JRST XCW1X ;NO. RIGHT ON TIME 1664: MOVE IOS,[XGPERR,,IODERR] ;SET ERROR BIT FOR USER. WE CONTINUE 1665: PUSHJ P,XGPSET ;UNTIL THE END OF THE NEXT LINE IN CH4 1666: SKIPE XGPERC ;ERROR CODE SET YET? 1667: JRST XCW1X ;AVOID DOING IT AGAIN 1668: PUSHJ P,XERR12 ;I MISSED IT! 1669: MOVEM AC1,XGPERC+1 ;SAVE CURRENT SCANLINE NUMBER FOR LOSER 1670: MOVE AC3,1(AC2) ;GET Y0 OF NEXT NODE 1671: MOVEM AC3,XGPERC+2 ;GIVE THAT TO THE LOSER TOO. 1672: XCW1X: MOVE AC3,(AC2) ;GET OLD LINK OUT. 1673: MOVEM AC3,XPENDH ;SET OLD LINK OUT INTO LIST HEAD. 1674: JUMPN AC3,XCW1A ;JUMP UNLESS LIST IS EMPTY. 1675: MOVEI AC3,XPENDH ;ADDRESS OF LIST HEAD. 1676: MOVEM AC3,XPENDT ;TAIL POINTS TO LIST HEAD. 1677: XCW1A: SKIPGE AC3,2(AC2) ;GET X0,,N 1678: JRST XCW1C ;THIS IS A TEXT NODE. 1679: HRRZM AC3,1(AC2) ;STORE N TO CLOBBER Y0. 1680: ANDCMI AC3,-1 ;LEFT SIDE ONLY IS X0 1681: SKIPL 4(AC2) ;DON'T BUGGER X0 IF DX<0 6/12/73 1682: SUB AC3,4(AC2) ;X0-DX 1683: MOVEM AC3,2(AC2) ;CLOBBER X0 WITH X0-DX. 1684: SKIPG AC3,3(AC2) ;GET THE WIDTH FIELD. 1685: JRST XCW1D ;THIS IS A PAGE NODE. CUT THE PAPER. 1686: CAILE AC3,SETN+=200 ;IS IT SMALL ENOUGH TO GET DONE QUICK? 1687: JRST XCW1B ;NO. THIS GOES IN THE WIDE VECTOR LIST. 1688: EXCH AC2,XASVLH ;STORE POINTER IN ACTIVE NARROW V. LIST HEAD 1689: MOVEM AC2,@XASVLH ;STORE OLD LIST IN NEWLY ACTIVATED. 1690: JRST XCW1 ;LOOK FOR MORE NEWLY ACTIVATED 1691: 1692: XCW1B: EXCH AC2,XALVLH ;STORE POINTER IN ACTIVE WIDE V. LIST HEAD 1693: MOVEM AC2,@XALVLH ;STORE OLD LIST IN NEWLY ACTIVATED. 1694: JRST XCW1 ;LOOK FOR MORE NEWLY ACTIVATED 1695: 1696: XCW1C: MOVEM AC1,1(AC2) ;SET STARTING LINE NUMBER. 1697: EXCH AC2,XATLH ;SET ACTIVE TEXT HEADER 1698: MOVEM AC2,@XATLH ;LINK NEW NODE TO OLD LIST. 1699: JRST XCW1 ;LOOK FOR MORE. 1700: 1701: XCW1D: SKIPG XGPPS3 ;TOP OF PAGE. IS THERE A BOTTOM MARGIN? 1702: JRST XCW1DA ;NO BOTTOM MARGIN: NO CUT 1703: PUSHJ P,QCUT ;CUT THE PAPER. 1704: MOVE TAC,XSCNLN 1705: CAIL TAC,=2000 1706: CAILE TAC,=2200 1707: JRST XCW1DA ;PAGE SIZE IS UNUSUAL 1708: MOVEI TAC,1 1709: IORM TAC,XFLAPB ;TURN ON A BIT TO MAKE IT FLAP 1710: XCW1DA: SETOM XSCNLN ;NEXT SCAN LINE IS 0 1711: MOVE TAC1,4(AC2) ;GET THE END OF FILE INDICATOR. 1712: EXCH AC2,XVNFL ;FREE THIS PAGE MARK NODE. 1713: MOVEM AC2,@XVNFL 1714: 1715: MOVEI AC2,0 ;FREE NARROW ACTIVE VECTORS 1716: EXCH AC2,XASVLH ;AC2←LIST HEADER; LIST HEADER←0 1717: XCW1E: SKIPN AC3,AC2 ;AC3←FIRST ELEMENT IN LIST 1718: JRST XCW1F 1719: MOVE AC2,(AC2) ;ADVANCE IN LIST. 1720: EXCH AC3,XVNFL ;FREE NODE THAT AC3 POINTS TO 1721: MOVEM AC3,@XVNFL 1722: JRST XCW1E 1723: 1724: XCW1F: MOVEI AC2,0 ;FREE WIDE ACTIVE VECTORS. 1725: EXCH AC2,XALVLH ;AC2←LIST HEADER; LIST HEADER←0 1726: XCW1G: SKIPN AC3,AC2 1727: JRST XCW1H 1728: MOVE AC2,(AC2) 1729: EXCH AC3,XVNFL 1730: MOVEM AC3,@XVNFL 1731: JRST XCW1G 1732: 1733: XCW1H: MOVEI AC2,0 ;FREE TEXT NODES. 1734: EXCH AC2,XATLH ;AC2←LIST HEADER; LIST HEADER←0 1735: XCW1I: SKIPN AC3,AC2 1736: JRST XCW1K 1737: MOVE AC2,(AC2) ;LINK AHEAD. 1738: XCW1J: MOVEI TAC,(AC3) 1739: EXCH AC3,XTNFL 1740: MOVEM AC3,@XTNFL 1741: SKIPE AC3,3(TAC) 1742: JRST XCW1J 1743: JRST XCW1I 1744: 1745: XCW1K: SETOM XACT4 ;NODES HAVE BEEN FREED 1746: JUMPL TAC1,XCW6 ;WAKE COMPILER UNLESS EOF. 1747: MOVEI TAC1,XCIBEG 1748: MOVEM TAC1,XDISP2 ;SET DISPATCH THRU THE TOP. 1749: JRST CPOPJ1 ;SKIP RETURN INDICATES EOF. 1750: 1751: XCW3: SKIPN XALVLH ;ANY WIDE VECTORS? 1752: SKIPE XASVLH ;NO. ANY NARROW VECTORS? 1753: JRST .+2 ;THERE ARE SOME ACTIVE VECTORS. 1754: JRST XCW5 ;NO VECTORS ACTIVE. 1755: MOVEM P,XGPTMP ;SAVE P FOR LATER. 1756: MOVSI AC3,XNVC ;PICKUP THE NARROW VECTOR CODE 1757: BLT AC3,XNVC3 ;LOAD NVC INTO THE AC'S. 1758: MOVEI AC1,XASVLH ;POINTER TO FIRST VECTOR. 1759: JRST XNVC1 ;EXECUTE THE CODE IN THE AC'S. 1760: 1761: XCW4: SKIPN XALVLH ;ANY WIDE VECTORS? 1762: JRST XCW4A ;NO. AVOID THIS STUFF. 1763: MOVE AC3,[XWVC,,XWVC1] 1764: BLT AC3,XWVC2 1765: MOVEI AC3,XCW4A 1766: HRRM AC3,XWVC3 ;SET RETURN ADDRESS. 1767: MOVEI AC1,XALVLH 1768: JRST XNVC1 ;DO LONG VECTORS. RETURN TO XCW4A 1769: 1770: XCW4A: MOVE P,XGPTMP ;HERE AFTER ALL VECTORS DONE 1771: XCW5: MOVEI AC3,XATLH ;FOR ACTIVE TEXT LIST. 1772: MOVE IOS,[SCANX,,SCAN] ;SOURCE,,DESTINATION 1773: BLT IOS,SCAND ;MOVE CODE INTO THE AC'S. 1774: ;IOS,TAC,TAC1,AC2,3 ARE 'FREE' 1775: ;P IS FOR STACK. AC1=MAJOR SCANLINE #. 1776: XCW5A: MOVEI AC2,(AC3) ;LINK AHEAD. AC2=LAST ONE DONE. 1777: XCW5B: SKIPN AC3,(AC2) ;GET THE FORWARD LINK 1778: JRST XCW6 ;THERE IS NONE LEFT. 1779: PUSH P,AC2 1780: MOVE AC1,XSCNLN 1781: SUB AC1,1(AC3) ;RELATIVE SCAN LINE NUMBER. 1782: PUSHJ P,4(AC3) ;EXECUTE THE NODE. 1783: POP P,AC2 1784: MOVE AC3,(AC2) ;SET UP AGAIN. 1785: AOSGE 2(AC3) ;COUNT A LINE USED UP. 1786: JRST XCW5A ;NODE IS STILL ACTIVE. 1787: ;DELINK HEADER FROM ACTIVE LIST. 1788: MOVE TAC,(AC3) ;GET THE LINK TO NEXT ACTIVE TEXT NODE. 1789: MOVEM TAC,(AC2) ;STORE INTO THE GUY WHO POINTS HERE. 1790: ;ADD HEADER AND LINKED BLOCKS TO FREE LIST. 1791: XCW5C: MOVEI TAC,(AC3) ;SAVE THIS BLOCK ADDRESS 1792: EXCH AC3,XTNFL ;LINK THIS BLOCK INTO TEXT NODE FREE LIST. 1793: MOVEM AC3,@XTNFL ;STORE OLD FL POINTER INTO NEW BLOCK. 1794: SKIPE AC3,3(TAC) ;SKIP IF THERE IS NO FURTHER LINK 1795: JRST XCW5C ;GIVE BACK ANOTHER BLOCK. 1796: SETOM XACT4 ;WE WILL KICK CH4. 1797: JRST XCW5B ;DON'T ADVANCE AC2. 1798: 1799: XCW6: SKIPN XACT4 1800: POPJ P, 1801: CONO PI,1B24!<1⊗<7-XGPC2N>> ;ACTIVATE INTERRUPT ON COMPILER CHANNEL. 1802: MOVE TAC,[JRST P2CH4S] 1803: MOVEM TAC,P2CH4E ;CLOBBER CHANNEL 4 EXIT ROUTINES. 1804: POPJ P, ;DISMISS CHANNEL 2. 1806: ; MODE 0 I-LEVEL 'SCAN PHASE' 1807: ;ENTER SCANE FOR LEFT SIDE (EVEN) 1808: ;ENTER SCANO FOR RIGHT SIDE (ODD) 1809: ;IOS, TAC, AC3 ARE IN USE. TAC1 IS FREE, P IS STACK. 1810: 1811: SCANX: PHASE 4 1812: SCAN:: MOVE AC3,(AC3) ;4 CALLED BY JSP AC3, GET AOBJN PTR 1813: JUMPL TAC,SCANO ;5 JUMP TO ODD SIDE SCAN 1814: SCANE:: HLRZ IOS,@(AC3) ;6 LOAD DATA 1815: DATAO XGP,IOS ;7 SEND DATA 1816: AOBJN AC3,SCANE ;10 LOOP IN MINOR COMMAND 1817: JRST (AC3) ;11 RETURN TO COMMAND BUFFER 1818: SCANO:: DATAO XGP,@(AC3) ;12 SEND DATA 1819: AOBJN AC3,SCANO ;13 LOOP 1820: SCAND:: JRST (AC3) ;14 RETURN. END OF PHASED CODE. 1821: DEPHASE 1822: 1823: ;REGISTER ASSIGNMENTS: 1824: ;IOS FREE EXCEPT CLOBBERED INSIDE SCAN 1825: ;TAC HAS RELATIVE LINE NUMBER AND ODD/EVEN INDICATOR 1826: ;TAC1 FREE 1827: ;P STACK 1828: ;AC1 MAJOR SCANLINE NUMBER 1829: ;AC2 RETURN ADDRESS FOR CURRENT MINOR COMMAND 1830: ;AC3 ARGUMENT ADDRESS FOR SCAN. 1831: 1832: ;NARROW VECTOR PROCESSING: 1833: XNVC: PHASE 0 ;AC1 SET UP INITIALLY. 1834: XNVC1:: MOVEI AC3,(AC1) ;0 LINK AHEAD. AC1=LAST ONE DONE. 1835: XNVC2:: SKIPN AC1,(AC3) ;1 GET THE FORWARD LINK 1836: XWVC3:: JRST XCW4 ;2 THERE IS NONE. ;*CLOBBERED FOR WIDE 1837: MOVE AC2,4(AC1) ;3 DX 1838: ADDB AC2,2(AC1) ;4 X←X+DX 1839: HLRZ AC2,AC2 ;5 GET X AS A RIGHT SIDE QUANTITY 1840: CONO XGP,SETX(AC2) ;6 SET X COLUMN REGISTER 1841: CONO XGP,@3(AC1) ;7 SEND THE WIDTH. 1842: SOSLE 1(AC1) ;10 DECREMENT N 1843: JRST XNVC1 ;11 ADVANCE TO THE NEXT VECTOR 1844: XNVC3:: JRST XNVC4 ;12 RUN THE CODE TO FLUSH THIS VECTOR 1845: DEPHASE 1846: 1847: XWVC: PHASE 10 ;HERE FOR WIDE VECTORS. 1848: XWVC1:: CONSO XGP,NZ ;10 WAIT HERE FOR DONE 1849: JRST XWVC1 ;11 LOOP. 1850: SOSLE 1(AC1) ;12 1851: JRST XNVC1 ;13 1852: XWVC2:: JRST XNVC4 ;14 1853: DEPHASE ;15, 16, 17 ARE AC1,2,3 1854: 1855: XNVC4: MOVE AC2,(AC1) ;GET THE LINK TO NEXT ACTIVE VECTOR 1856: MOVEM AC2,(AC3) ;STORE INTO THE GUY WHO POINTS HERE. 1857: EXCH AC1,XVNFL ;LINK TO VECTOR NODE FREE LIST. 1858: MOVEM AC1,@XVNFL ;STORE OLD FL POINTER INTO NEW BLOCK. 1859: SETOM XACT4 ;WE WILL KICK CHANNEL 4. 1860: JRST XNVC2 ;DON'T ADVANCE IN LIST. 1862: ; ROUTINES TO MANIPULATE COMMAND HEADER BLOCKS. 1863: ;SCHB, OFFCHB, ACHB 1864: ;ALL OF THESE ARE CALLED BY JSP AC1, 1865: ;MOST REQUIRE THAT AC2, AC3 BE SET UP WITH MINIMUM AND MAXIMUM VALUES. 1866: ;CAUTION----DON'T CLOBBER DAT INSIDE THESE ROUTINES! 1867: 1868: ;SEARCH FOR A COMMAND BLOCK WITH THE RIGHT PARAMETERS, ELSE MAKE ONE. 1869: ;AC2 = MIN, AC3 = MAX 1870: SCHB: SKIPN UUO,XCHBGO ;HAVE WE ANY BLOCKS AT ALL? 1871: JRST FCHB ;NO. WE SHALL MAKE THE FIRST. 1872: MOVEI UUO,4(UUO) ;POINT TO FIRST EXECUTABLE 1873: SCHB1: MOVEI UCHN,(UUO) ;LINK ON 1874: CAIN AC2,@(UCHN) 1875: CAIE AC3,@1(UCHN) 1876: JRST SCHB2 ;NO MATCH. LOOK AT NEXT LINK 1877: CAIGE PROG,3(TEM) ;IS THERE ROOM FOR MORE? 1878: PUSHJ P,ADDNOD ;NO. ADD A NODE. RESET TEM,PROG. 1879: MOVEI AC3,1(TEM) ;GET POINTER TO NEXT AVAIL. WORD. 1880: EXCH AC3,7(UCHN) ;SET NEW INTER-GROUP LINK. 1881: JRST ADBH1 ;GO ADD THE DATA BLOCK HEADER 1882: 1883: SCHB2: HRRZ UUO,2(UCHN) ;UUO SET WITH NEXT LINK 1884: CAIE UUO,CPOPJ ;WAS THIS THE LAST LINK? 1885: JRST SCHB1 ;NO. KEEP LOOKING ALONG LIST. 1886: ;MAKE A NEW COMMAND HEADER. 1887: 1888: ;ADD A COMMAND HEADER BLOCK. UCHN POINTS TO LAST CHB IN THE LIST. AC2, AC3 SET 1889: ACHB: CAIGE PROG,11(TEM) ;WE ARE ADDING 9 MORE WORDS. 1890: PUSHJ P,ADDNOD ;NO ROOM. ADD A NEW NODE. 1891: MOVEI UUO,1(TEM) ;POINTER TO NEXT AVAIL CELL. 1892: HRRM UUO,2(UCHN) ;CLOBBER LAST GUY'S RETURN ADDRESS. 1893: JRST FCHB1 ;NOW MAKE THE COMMAND HEADER BLOCK 1894: 1895: ;FCHB CALLED FROM SCHB TO MAKE FIRST COMMAND BLOCK. GET TEXT NODE FROM FREE LIST. 1896: FCHB0: CONO PI,PION 1897: JSR X2DISP ;SET CO-ROUTINE ADDRESS FOR LATER 1898: ;*4 1899: FCHB: CONO PI,PIOFF 1900: SKIPN UUO,XTNFL ;GET DATA FROM THE FREE LIST 1901: JRST FCHB0 1902: MOVE UCHN,(UUO) 1903: MOVEM UCHN,XTNFL 1904: CONO PI,PION 1905: MOVEM UUO,XCHBGO 1906: SETZM XNODUS ;COUNT OF NODES IN THIS LINE. 1907: SETZM (UUO) ;MAJOR LINK 1908: SETZM 3(UUO) ;LINK-2 1909: MOVEI TEM,3(UUO) ;PDL POINTER. LEFT HALF ZERO. 1910: MOVEI PROG,TNSIZE-1(UUO) ;LAST ADDRESS THAT CAN BE USED 1911: ;CAIGE PROG,n(TEM) WILL SKIP 1912: ;IF n MORE THINGS CAN BE PUSHED. 1913: MOVE DSER,TEM ;WE ARE NOT INSIDE A TEXT STRING. 1914: 1915: ;MAKE COMMAND HEADER BLOCK. AC2 = MIN, AC3 = MAX 1916: FCHB1: PUSH TEM,[CAIL AC1,0] ;0 STUFF INSTRUCTION 1917: HRRM AC2,(TEM) ;SET MINIMUM 1918: MOVEI UCHN,(TEM) ;SET UCHN TO POINT TO HEADER. 1919: PUSH TEM,[CAIL AC1,0] ;1 ANOTHER INSTRUCTION. 1920: HRRM AC3,(TEM) ;SET ARGUMENT IN INSTRUCTION 1921: CAMLE AC3,XHMAX ;IS THIS BIGGER THAN CURRENT MAX? 1922: MOVEM AC3,XHMAX ;YES. SET MAXIMUM VALUE OF SCAN LINE 1923: PUSH TEM,[JRST CPOPJ] ;2 SET RETURN ADDRESS. 1924: PUSH TEM,[MOVEI TAC,(AC1)] ;3 MORE CODE 1925: PUSH TEM,[SUBI TAC,@0] ;4 MORE CODE 1926: HRRM UCHN,(TEM) ;FIX ADDRESS PART 1927: PUSH TEM,[ROT TAC,-1] ;5 MORE CODE. 1928: MOVEI AC3,2(UCHN) ;SET UP RETURN ADDRESS. 1929: ;HERE TO ADD A DATA BLOCK HEADER TO COMMAND BLOCK ADDRESSED BY UCHN 1930: ADBH1: PUSH TEM,[JSP AC2,0] ;SET HEADER WORD 1931: MOVEI UUO,2(TEM) 1932: HRRM UUO,(TEM) ;SET JUMP ADDRESS 1933: PUSH TEM,AC3 ;SET RETURN ADDRESS. 1934: JRST (AC1) 1935: 1936: ;HERE TO OFFSET THE MIN,MAX VALUES. OFFSET IS IN AC3. 1937: OFFCHB: MOVE UCHN,XCHBGO 1938: MOVEI UCHN,4(UCHN) ;OFFSET TO FIRST INSTRUCTION 1939: OFFCH1: ADDM AC3,(UCHN) 1940: ADDM AC3,1(UCHN) 1941: HRRZ UUO,2(UCHN) 1942: CAIN UUO,CPOPJ 1943: JRST (AC1) ;RETURN WITH UCHN SET UP. 1944: MOVEI UCHN,(UUO) 1945: JRST OFFCH1 1946: 1947: ;ADDNOD MAKES A NEW TEXT NODE. TEM IS OLD PDL, AT LEAST 1 NEEDED IN OLD BLOCK. 1948: ;CALLED WITH A PUSHJ. CLOBBERS UUO. RETURNS WITH TEM=DSER=NEW PDL. PROG=LAST. 1949: ADDND2: PUSHJ P,XERR10 ;ERROR-LINE TOO COMPLEX 1950: POP P,(P) ;FLUSH RETURN ADDRESS. 1951: JRST XCIG2A ;SET ERROR BIT. 1952: 1953: ADDND1: CONO PI,PION 1954: CAML DSER,XNTNOD ;HOW MANY NODES IN USE? 1955: JRST ADDND2 ;TOO MANY NODES ARE IN USE. 1956: JSR X2DISP ;WAIT FOR A FREE NODE. 1957: JRST .+2 1958: ADDNOD: AOS DSER,XNODUS 1959: CONO PI,PIOFF 1960: SKIPN UUO,XTNFL ;GET FROM FREE LIST 1961: JRST ADDND1 ;NONE THERE 1962: MOVE DSER,(UUO) 1963: MOVEM DSER,XTNFL 1964: CONO PI,PION 1965: PUSH TEM,[JRST] ;SET JRST AT END OF OLD BLOCK. 1966: MOVEI DSER,4(UUO) ;JUMP TARGET 1967: HRRM DSER,(TEM) 1968: MOVEI TEM,3(UUO) ;NEW PDL. 1969: MOVEI PROG,TNSIZE-1(UUO) ;LAST ADDRESS THAT CAN BE USED 1970: MOVE DSER,XCHBGO 1971: EXCH UUO,3(DSER) ;SET LINK TO US. 1972: MOVEM UUO,(TEM) ;OLD LINK IN US. 1973: MOVE DSER,TEM 1974: POPJ P, 1976: ; XGP LINE COMPILER CO-ROUTINES 1977: ;*4 HERE FOR FIRST COMPILER ACTIVATION. 1978: XCPINI: MOVE TAC,XFREBA ;GET THE BASE OF FREE SPACE. 1979: ADD TAC,XFCADR ;ADD RELOCATION OF THE FC 1980: MOVEM TAC,XVNFL ;BASE OF VECTOR NODE FREE LIST 1981: MOVE TAC1,XNVNOD ;MAKE THIS MANY NODES. 1982: ADDI TAC,VNSIZE ;THIS IS THE NODE SIZE 1983: MOVEM TAC,-VNSIZE(TAC) ;STORE LINK 1984: SOJG TAC1,.-2 ;LOOP LINKING BLOCKS. 1985: SETZM -VNSIZE(TAC) ;LAST LINK IS ZERO. 1986: MOVEM TAC,XTNFL ;BASE OF TEXT NODE FREE LIST. 1987: MOVE TAC1,XNTNOD ;THIS MANY 1988: ADDI TAC,TNSIZE ;THIS SIZE 1989: MOVEM TAC,-TNSIZE(TAC) 1990: SOJG TAC1,.-2 1991: SETZM -TNSIZE(TAC) ;CLEAR OUT LAST LINK. 1992: 1993: SETZM XLFTKF ;SET THE KERN FLAG OFF. 1994: MOVE TAC,XGPPS1 ;GET THE SIZE OF TOP MARGIN 1995: MOVEM TAC,XCYPOS ;CURRENT (DEFAULT) Y POSITION. 1996: SETZM XGPLYP ;LAST Y POSITION WRITTEN WAS 0 1997: SETZM XTOFRM ;XGP IS AT 'TOP OF FORM' 1998: MOVE TAC,XFTADR ;GET THE FONT ADDRESS OF FONT 0 1999: ADD TAC,XFCADR ;ADD RELOCATION OF FONT COMPILER 2000: HRRZM TAC,XFTCAD ;SAVE AS RELOCATED ADDRESS OF CURRENT FONT. 2001: MOVE J,XGPLMR ;SET INITIAL COLUMN AT LEFT MARGIN. 2002: LDB TAC,[POINT 5,(TAC),22] ;GET THE COLUMN POS ADJUSTMENT 2003: SUBI J,(TAC) ;AND USE IT TO BUGGER THE COLUMN POSITION. 2004: SETZM XGPPG2 ;PAPER PAGE ← 0 2005: MOVE P,XGPPDL ;PDL FOR COMPILER. 2006: MOVEI PID,P2PID ;NOT RANDOMNESS 2007: 2008: ;HERE WE PREPARE TO COMPILE A VECTOR NODE OR A TEXT NODE. 2009: 2010: XCI: JSP AC3,BFOSET ;SET UP AOBJN POINTER IN TAC 2011: JUMPGE TAC,XCI0 ;JUMP IF THERE'S NO DATA TO BE HAD. 2012: ;REGISTER USE IN THE COMPILER. 2013: ;LINE INITIALIZATION STUFF. 2014: ;J ← COLUMN COUNT IN XGP. 2015: ;TEM ← POINTER TO NEXT FREE WORD IN BUFFER. 2016: ;DSER ← LOCATION OF CURRENT AOBJN WORD IN TEXT NODE. 2017: ;UCHN ← LOCATION OF CURRENT COMMAND HEADER BLOCK. 2018: ;TAC1←5 INITIAL NUMBER OF BYTES IN THE WORD. 2019: XCIA: MOVEI TAC1,5 2020: SETOM XLBL ;CURRENT BASELINE POSITION. 2021: SETZB TEM,XHMAX ;CURRENT MAXIMUM HEIGHT 2022: SETZB DSER,XCHBGO ;FLAG SCHB THERE ARE NO COMMAND BLOCKS YET. 2023: SETZB UCHN,XVNODE ;NO VECTORS TO QUEUE YET. 2024: 2025: MOVE DAT,@XFTCAD ;DEFINE CURRENT FONT PARAMETERS. 2026: HLRZM DAT,XCFBL ;BASE LINE. 2027: ANDI DAT,17777 ;OMIT THE COLUMN POS ADJ BITS 2028: HRRZM DAT,XCFH ;FONT HEIGHT 2029: LDB DAT,[POINT 5,@XFTCAD,22];GET THE COLUMN POS ADJUSTMENT 2030: MOVEM DAT,XCFCPA ;SAVE COLUMN POS ADJ 2031: 2032: ;CHARACTER BY CHARACTER LOOP. 2033: XCI1: JSP AC3,XCIG ;GET A CHARACTER 2034: CAIN DAT,177 ;SKIP IF NOT ESCAPE. 2035: JRST XCI2 ;PROCESS DLE 2036: CAIG DAT,15 2037: CAIG DAT,10 2038: JUMPN DAT,XCI2A ;JUMP IF NORMAL CHARACTER. 2039: JUMPE DAT,XCI1 ;THROW OUT NULLS. 2040: ;PROCESS SPECIALS HERE (TAB, LF, VT, FF, CR) 2041: JRST @.+1-11(DAT) ;DAT HAS CODE BETWEEN 11 AND 15 2042: XCI1A ;HT (11) 2043: XCI4 ;LF (12) 2044: XCI2A ;VT (13) IS JUST ANOTHER CHARACTER. 2045: XCI4 ;FF (14) 2046: XCI1B ;CR (15) 2048: ; HERE TO QUEUE A TEXT NODE. 2049: ;LINE OVERFLOW ROUTINES. 2050: XCI1D: MOVE J,XGPLMR ;SET MARGIN. (CR) 2051: SUB J,XCFCPA ;ADJUST COLUMN POSITION 2052: XCI1F: MOVEI DAT,0 ;LINE OVERFLOW. 2053: 2054: ;HERE AT END OF LINE. DAT HAS THE BREAK CHARACTER. ONLY FF IS SIGNIFICANT. 2055: XCI4: SKIPN XGPAT2 ;THIS SHOULDN'T SKIP EXCEPT IF SCREWED 2056: SKIPE XGPHIP ;HEADING IN PROGRESS? 2057: JRST XCI4A ;YES. AVOID CLOBBERING IT. 2058: MOVE AC3,MTB(TAC1) ;HERE AT END OF A CHARACTER LINE. 2059: ANDM AC3,(TAC) ;MASK OUT USED UP BYTES. 2060: JSP AC3,BFNSET ;ADVANCE BUFFER POINTERS. 2061: JRST XCI4B 2062: 2063: XCI4A: MOVE TAC,XSVCAD 2064: SKIPE XGPHIP 2065: MOVEM TAC,XFTCAD 2066: SETZM XGPHIP ;NO LONGER HEADING IN PROGRESS 2067: SETZM XGPAT2 ;DRD STRIKES AGAIN. 2068: XCI4B: SKIPG UUO,XHMAX ;IS THE MAXIMUM HEIGHT SET? 2069: MOVE UUO,XCFH ;NO. SET IT FROM THE CURRENT FONT HEIGHT 2070: MOVEM UUO,XHMAX 2071: JUMPE TEM,XCI5 ;JUMP IF THERE IS NO COMMAND GROUP. 2072: PUSH TEM,[JRST @(AC2)] ;STOP THE CURRENT COMMAND GROUP. 2073: MOVE TAC,XCHBGO ;GET THE ADDRESS OF THIS TEXT NODE. 2074: MOVNM UUO,2(TAC) ;SAVE THE ACTIVE LINE COUNT. 2075: MOVE TAC1,XCYPOS ;GET THE Y POSITION. 2076: MOVEM TAC1,1(TAC) ;STORE IN TEXT NODE. 2077: EXCH TAC1,XGPLYP ;STORE THIS AS THE LAST Y WE DID. 2078: SETZM (TAC) ;ZERO THE LINK OUT 2079: CONO PI,PIOFF 2080: MOVEM TAC,@XPENDT ;STORE THRU THE TAIL. 2081: MOVEM TAC,XPENDT ;STORE NEW QUEUE TAIL 2082: CONO PI,PION 2083: CAMLE TAC1,XGPLYP ;IS Y0 > OR = THE LAST Y WE DID? 2084: PUSHJ P,XGPOOO ;OUT OF ORDER. 2085: SETOM XTOFRM ;FLAG TEXT IS ON PAGE. 2086: XCI5: CAIN DAT,14 ;FF? 2087: JRST XCI6A ;YES. 2088: SKIPN UUO,XVNODE ;ANY VECTOR NODE TO QUEUE? 2089: JRST XCI6 ;NO. 2090: MOVE TAC1,1(UUO) ;GET THE Y0 OF THIS VECTOR 2091: MOVEM TAC1,XCYPOS ;USE AS THE Y0 OF THE NEXT TEXT 2092: EXCH TAC1,XGPLYP ;STORE AS THE LAST Y0 THAT WAS QUEUED 2093: CONO PI,PIOFF ;QUEUE THE VECTOR NODE. 2094: MOVEM UUO,@XPENDT 2095: MOVEM UUO,XPENDT 2096: CONO PI,PION 2097: CAMLE TAC1,XGPLYP 2098: PUSHJ P,XGPOOO ;OUT OF ORDER 2099: SETOM XTOFRM ;FLAG TEXT EXISTS ON PAGE. 2100: CAIN DAT,14 2101: JRST XCI6A ;IN CASE OF ACCIDENT HE ALWAYS ... 2102: JRST XCI6Z ;(DAT IS ZERO) 2103: 2104: XCI6: SKIPG DAT,XGPSLS ;SPECIAL LINE SPACE, IF ANY, 2105: MOVE DAT,XGPILS ;ELSE THE REGULAR LINE SPACE. 2106: SETZM XGPSLS ;(AND NO SPECIAL LINE SPACE ANYMORE) 2107: ADD DAT,XHMAX ;PLUS LINE HEIGHT. 2108: XCI6Z: ADDB DAT,XCYPOS ;PLUS Y0 OF THIS LINE, ICS Y0 OF NEXT LINE. 2109: SKIPG TAC,XGPPS2 2110: JRST XCI6ZZ ;PMAR=0 MEANS DON'T CUT UNLESS TOLD 2111: ADD TAC,XGPPS1 ;SUM OF TOP MARGIN+PAGE BODY SIZE 2112: CAIL DAT,(TAC) ;SKIP UNLESS WE NEED A FORM FEED HERE. 2113: JRST XCI6B ;HERE WE NEED A FORM FEED. 2114: XCI6ZZ: MOVSI TAC,XGPERR ;ERROR FLAG UP? 2115: TDNE TAC,XGPIOS ;? 2116: JRST XCI6E ;YES. SCREECH 2117: JRST XCI ;GO DO THE NEXT LINE. 2118: 2119: XCI6A: SETZM XGPPG2 ;REAL FF. PAPER PAGE ← 0 2120: XCI6B: MOVSI TAC,XGPERR ;IS THERE AN ERROR? 2121: TDNE TAC,XGPIOS 2122: JRST XCI6E ;ERROR. FAKE EOF. 2123: JSP AC3,BFOSET ;SEE IF THERE'S MORE DATA TO SEND 2124: JRST XCI6DX ;TAC<0 MEANS MORE DATA. 2125: 2126: XCI6E: PUSHJ P,PSYNCX ;HERE FOR ERROR. 2127: ANDCA TAC,XGPIOS ;CLEAR PRIMARY ERROR 2128: IORI TAC,IODERR ;TURN ON USER'S ERROR 2129: MOVEM TAC,XGPIOS 2130: SETZM XGPBIT ;WON'T RUN PAPER. 2131: PUSHJ P,XSYNCX 2132: MOVEI TAC,1 ;MAKE TAC>0 LIKE EOF. 2133: XCI6DX: SKIPN XTOFRM ;ANY TEXT ON THIS PAGE? 2134: JUMPL TAC,XCI6F ;NO. AVOID BLANK PAGES. (ONLY IF MORE DATA) 2135: JRST XCI6D 2136: 2137: XCI6C: CONO PI,PION ;RESTORE PI'S 2138: JSR X2DISP ;SET RESTART ADDRESS AND DISMISS. 2139: ;*4 2140: XCI6D: CONO PI,PIOFF 2141: SKIPN TAC1,XVNFL ;GET A FREE VECTOR. 2142: JRST XCI6C ;HAVE TO WAIT FOR A FREE NODE. 2143: MOVE DAT,(TAC1) ;GET LINK 2144: MOVEM DAT,XVNFL ;STORE LINK 2145: CONO PI,PION 2146: SETZM (TAC1) ;FIX LINK OUT 2147: SKIPG DAT,XGPPS2 ;PMAR 2148: SKIPA DAT,XCYPOS ;PMAR = 0 USE CURRENT Y POSITION AS A GUIDE 2149: ADD DAT,XGPPS1 2150: ADD DAT,XGPPS3 ;TOTAL PAGE SIZE 2151: MOVEM DAT,1(TAC1) ;STORE Y0 IN THE WORD. 2152: SETZM 2(TAC1) ;N=0 DENOTES VECTOR TYPE NODE. 2153: SETOM 3(TAC1) ;WIDTH<0 DENOTES PAGE NODE 2154: MOVEM TAC,4(TAC1) ;STORE POSITIVE FOR EOF. 2155: CONO PI,PIOFF ;QUEUE THE PAGE MARK NODE. 2156: MOVEM TAC1,@XPENDT ;STORE AT END OF QUEUE 2157: MOVEM TAC1,XPENDT ;UPDATE END OF QUEUE. 2158: CONO PI,PION 2159: SETZM XTOFRM ;NO TEXT ON PAGE ANY MORE. 2160: XCI6F: JUMPGE TAC,XCIP3 ;JUMP IF EOF 2161: MOVE TAC,XGPPS1 2162: MOVEM TAC,XCYPOS ;SET CURRENT Y POSITION. 2163: SETZM XGPLYP ;LAST Y QUEUED WAS 0 2164: AOS TAC1,XGPPG2 ;INCREMENT "PAPER PAGE" COUNT 2165: SKIPGE TAC,XGPHDW ;IS THERE AN AOBJN POINTER FOR HEADING? 2166: CAIG TAC1,1 ;YES. SKIP IF AFTER FIRST PAPER PAGE. 2167: JRST XCI ;NO HEADING OR FIRST PAPER PAGE. SEND DATA. 2168: XCIP2: SETOM XGPHIP ;HEADING IN PROGRESS 2169: MOVE TAC1,XFTCAD ;SAVE PRESENT FONT. 2170: MOVEM TAC1,XSVCAD ;SAVE IT. 2171: JRST XCIA ;GO DO THE HEADING 2172: 2173: XCIP3: JSR X2DISP ;EOF. DISMISS INTERRUPT. 2174: JRST .-1 ;IGNORE FURTHER INTERRUPTS. 2175: 2176: XGPOOO: MOVEI DAT,14 ;SET TO KILL TRANSFER 2177: MOVSI IOS,XGPERR 2178: PUSHJ P,XGPSET 2179: JRST XERR11 ;OUT OF ORDER 2181: ; MODE 0 GET NEXT CHARACTER 2182: BTB: POINT 7,(TAC),34 ;(BYTE THE BAG?) 2183: POINT 7,(TAC),27 2184: POINT 7,(TAC),20 2185: POINT 7,(TAC),13 2186: POINT 7,(TAC),6 2187: 2188: MTB: 0 2189: 377 2190: 77777 2191: 17,,-1 2192: 3777,,-1 2193: -1 ;NOT REDUNDANT! USED TO UNTAKE A CHARACTER 2194: 2195: ;HERE WHEN WE HAVE END OF HEADING DATA. 2196: XCIG4: MOVEI DAT,20 ;SET SPECIAL LINE SPACE COUNT 2197: MOVEM DAT,XGPSLS 2198: JRST XCI1F ;MAKE END OF LINE OCCUR. 2199: 2200: XCIG3: SKIPN XGPAT2 ;PAGE NUMBER HACK? 2201: JRST XCIG4 ;NO. JUST HEADING HACK 2202: SETZM XGPAT2 ;CLEAR PAGE NUMBER CELL 2203: MOVE TAC,XGPAT0 ;RESTORE TAC, TAC1 2204: MOVE TAC1,XGPAT1 ;GET NEXT CHARACTER 2205: 2206: ; JSP AC3,XCIG TO GET NEXT CHARACTER INTO DAT 2207: XCIG: SOJL TAC1,XCIG1 ;COUNT DOWN IN WORD. 2208: LDB DAT,BTB(TAC1) ;GOBBLE A BYTE 2209: JRST (AC3) ;RETURN 2210: XCIG1: MOVEI TAC1,5 ;HERE THE WORD RAN OUT. 2211: AOBJN TAC,XCIG ;ADVANCE TO NEXT WORD. 2212: SKIPN XGPHIP ;HEADING IN PROGRESS OR 2213: SKIPE XGPAT2 ;ARE WE IN PAGE NUMBER HACK? 2214: JRST XCIG3 ;YES. DO IT 2215: PUSH P,AC3 ;NO NEXT WORD. SAVE RETURN 2216: PUSH P,AC1 2217: JSP AC3,BFNSET ;DO THE BUFFER FROTZ 2218: JSP AC3,BFOSET 2219: POP P,AC1 2220: POP P,AC3 ;RESTORE RETURN ADDRESS 2221: JUMPL TAC,XCIG ;JUMP IF THERE'S DATA LEFT. 2222: XCI0: MOVE DAT,XGPWSZ ;NO DATA LEFT. IS THIS CLOSE TIME? 2223: JUMPE DAT,XCI3 ;JUMP IF CLOSE UUO DONE. 2224: ;WE RAN OUT OF DATA WITHOUT A CLOSE UUO. 2225: PUSHJ P,XERR5 ;SET DATA MISS ERROR CODE. 2226: XCIG2A: MOVSI IOS,XGPERR ;SET ERROR STATUS. 2227: PUSHJ P,XGPSET 2228: XCI3: MOVEI DAT,14 ;HERE FOR END OF DATA. 2229: JRST XCI4A ;DO A FORM-FEED. 2231: ; HERE FOR SPECIALS 2232: ;H. TAB 2233: XCI1A: MOVE AC3,XFTCAD 2234: MOVE AC3,41(AC3) ;LOAD AOBJN POINTER 2235: LDB AC3,[POINT 9,(AC3),8] ;GET WIDTH OF A SPACE. 2236: JUMPE AC3,XCI1 ;IF A SPACE IS ZERO WIDTH, SO IS A TAB 2237: ADDI J,(AC3) ;ADVANCE AT LEAST ONE SPACE. 2238: LSH AC3,3 ;TIMES 8 2239: SUB J,XGPLMR ;TAB. COMPUTE DISTANCE FROM MARGIN 2240: IDIVI J,(AC3) ;QUOTIENT IN J REMAINDER IN DAT 2241: JUMPE DAT,.+2 2242: ADDI J,1 2243: IMULI J,(AC3) 2244: ADD J,XGPLMR ;ADD THE MARGIN SIZE BACK IN. 2245: JRST XCI1C ;NOW WE LOOK LIKE A COLUMN SELECT 2246: 2247: XCI1B: MOVE J,XGPLMR ;HERE FOR CR. LOAD LEFT MARGIN 2248: ;AND DO A COLUMN SELECT. 2249: XCI1C: SUB J,XCFCPA ;MAKE COLUMN ADJUSTMENT 2250: ;HERE TO DO SPECIAL COL SEL FROM KERNING FONT. 2251: XCI1CA: CAMN TEM,UCHN ;IS THIS MCG EMPTY? 2252: JRST XCI1 ;YES. DO COLUMN SELECT BY AN NON-EMPTY MCG 2253: CAIGE PROG,2(TEM) ;ROOM LEFT FOR THIS AND JUMP? 2254: PUSHJ P,ADDNOD ;NO. ADD A NEW TEXT NODE. 2255: PUSH TEM,[CONO XGP,SETX] 2256: ADDM J,(TEM) 2257: MOVE DSER,TEM ;DSER NO LONGER POINTS TO AOBJN POINTER. 2258: JRST XCI1 2260: ; HERE TO PROCESS RUBOUT 2261: ;HERE FOR RUBOUT. - GET NEXT CHARACTER. 2262: XCI2: JSP AC3,XCIG ;HERE FOR DLE. GET NEXT - PROCESS AS NORMAL 2263: CAIGE DAT,XCI2ZL 2264: JRST @XCI2Z(DAT) ;DISPATCH THRU TABLE 2265: CAIL DAT,20 ;TREAT '177 '20 THRU '177 '24 AS LINE SPACE 2266: CAILE DAT,24 2267: JRST XCI2A ;TREAT AS NORMAL 2268: MOVEI DAT,0 ;TREAT AS LINE-FEED 2269: JRST XCI4 ;SINCE ALL CAUSE SPACING ON THE LPT. 2270: 2271: XCI2Z: XCI2A ;'177 '0 IS NORMAL 2272: ESC1 ;'177 '1 IS ESCAPE 1 2273: ESC2 ;'177 '2 IS ESCAPE 2 2274: ESC3 ;'177 '3 IS ESCAPE 3 2275: ESC4 ;'177 '4 IS ESCAPE 4 2276: XCI2ZL←←.-XCI2Z 2277: 2278: ;HERE FOR '177 '001 - XGP ESCAPE 1. 2279: ESC1: JSP AC3,XCIG ;GET NEXT CHARACTER 2280: CAIGE DAT,40 ;IS THIS A COMMAND OR FONT SELECT 2281: JRST ESC1A ;FONT SELECT OR ILLEGAL 2282: CAIL DAT,XCI2YL+40 2283: JRST XCI1 ;ILLEGAL COMMAND. GET NEXT CHARACTER 2284: JRST @XCI2Y-40(DAT) 2285: XCI2Y: ES1.0 ;'177 '001 '040 COLUMN SELECT 2286: ES1.1 ;'177 '001 '041 UNDERSCORE 2287: ES1.2 ;'177 '001 '042 LINE SPACE SET. 2288: ES1.3 ;'177 '001 '043 FONT BASE LINE TWIDDLE. 2289: ES1.4 ;'177 '001 '044 PAPER PAGE NUMBER 2290: ES1.5 ;'177 '001 '045 SET&PRINT HEADING. 2291: ES1.6 ;'177 '001 '046 START UNDERLINE. 2292: ES1.7 ;'177 '001 '047 STOP UNDERLINE. 2293: XCI2YL←←.-XCI2Y 2294: 2295: ES1.0: MOVEI AC2,2 ;2 BYTES 2296: PUSHJ P,GLOM 2297: ANDI AC1,3777 ;REDUCE TO REASONABILITY 2298: MOVEI J,(AC1) 2299: JRST XCI1C ;GO SET COLUMN POSITION. 2300: 2301: ES1.7: EXCH J,XUSBEG ;SPECIAL UNDERSCORE COMMAND 2302: JRST ES1.1X 2303: ES1.1: HRROS XUSBEG ;FLAG NORMAL UNDERSCORE COMMAND 2304: ES1.1X: JUMPE TEM,ES1.1A 2305: CAIGE PROG,2(TEM) ;ROOM TO END THIS COMMAND? 2306: PUSHJ P,ADDNOD ;NO. ADD MORE SPACE. 2307: CAME UCHN,TEM ;IS THERE AN MCG IN PROGRESS? 2308: PUSH TEM,[JRST @(AC2)] ;YES. CLOSE IT. 2309: ES1.1A: JSP AC3,XCIG ;GET SCAN LINE NUMBER 2310: TRNE DAT,100 ;NEGATIVE? 2311: ORCMI DAT,77 ;YES. SIGN EXTEND. 2312: SKIPGE AC2,XLBL ;LINE BASE-LINE SET YET? 2313: MOVE AC2,XCFBL ;NOT YET. DO SO NOW. 2314: MOVEM AC2,XLBL 2315: ADD AC2,DAT 2316: MOVEI AC3,1(AC2) ;GET MAXIMUM 2317: JSP AC1,SCHB ;SEEK FOR APPROPRIATE CHB, ELSE MAKE ONE. 2318: CAIGE PROG,6(TEM) ;ROOM FOR 6 LEFT? 2319: PUSHJ P,ADDNOD ;NO. ADD ANOTHER NODE. 2320: PUSH TEM,[CONO XGP,SETX] 2321: ADDM J,(TEM) ;SET COLUMN SELECT CODE 2322: PUSH TEM,[CONO XGP,SETN] 2323: SKIPL XUSBEG ;SKIP IF NORMAL US. 2324: JRST ES1.7B ;SPECIAL US. 2325: MOVEI AC2,2 2326: PUSHJ P,GLOM ;READ 2 BYTES 2327: ANDI AC1,7777 2328: ES1.1C: ADDM AC1,(TEM) 2329: ADDI J,(AC1) ;GRONK OUR COLUMN POSITION APPROPRIATELY 2330: PUSH TEM,[CONSO XGP,NZ] 2331: MOVEI UUO,(TEM) 2332: PUSH TEM,[JRST] 2333: HRRM UUO,(TEM) 2334: ES1.1B: PUSH TEM,[JRST @(AC2)] 2335: MOVE UCHN,TEM 2336: MOVE DSER,TEM 2337: JRST XCI1 2338: 2339: ES1.7B: MOVE AC1,XUSBEG 2340: SUBI AC1,(J) 2341: JUMPGE AC1,ES1.1C 2342: MOVEI AC1,0 2343: JRST ES1.1C 2344: 2345: ES1.2: JSP AC3,XCIG 2346: MOVEM DAT,XGPSLS ;SET SPECIAL LINE SPACE 2347: JRST XCI1F 2348: 2349: ESC1A: CAILE DAT,17 ;SKIP IF FONT SELECT 2350: JRST XCI1 ;THIS IS A CODE FROM 20 TO 37. RESERVED. 2351: MOVEM J,1(P) ;SAVE COLUMN ADDRESS. NOTE!!! DON'T DO PUSHJ 2352: ADD J,XCFCPA ;ADD ADJUSTMENT WHEN LEAVING FONT 2353: SKIPN UUO,XFTADR(DAT) ;SEE IF THERE'S A FONT HERE 2354: MOVE UUO,XFTADR ;NONE THERE. USE FONT 0 2355: ADD UUO,XFCADR ;RELOCATE THE FONT BASE. 2356: HRRZM UUO,XFTCAD ;SAVE AS BASE OF CURRENT FONT 2357: LDB DAT,[POINT 5,(UUO),22] ;GET NEW COLUMN POS ADJ 2358: MOVEM DAT,XCFCPA ;SAVE IT 2359: SUBI J,(DAT) ;AND ADJUST COLUMN POSITION 2360: HRRZ DAT,(UUO) ;GET THE NEW FONT HEIGHT 2361: ANDI DAT,17777 ;MASK OFF THE COLUMN POSITION ADJUST FIELD 2362: HLRZ UUO,(UUO) ;AND THE NEW BASELINE 2363: CAMN DAT,XCFH ;COMPARE OLD AND NEW HEIGHTS 2364: CAME UUO,XCFBL ;OLD AND NEW BASELINES 2365: JRST ESC1B ;FONTS ARE NOT COMPATABLE 2366: CAME J,1(P) ;DID COLUMN POSITION CHANGE? 2367: JRST XCI1CA ;YES. DO A COLUMN SELECT NOW. 2368: JRST XCI1 ;FOR COMPATABLE FONTS, NO EXTRA WORK 2369: 2370: ES1.3: JSP AC3,XCIG ;GET NEXT CHARACTER 2371: CAIL DAT,100 2372: ORCMI DAT,177 2373: HLRZ UUO,@XFTCAD ;GET REAL BASE-LINE 2374: ADD UUO,DAT ;ADD THE TWIDDLE 2375: JRST ESC1C ;PRETEND WE SAW A NEW FONT. 2376: 2377: ESC1B: MOVEM DAT,XCFH ;STORE NEW HEIGHT 2378: ESC1C: MOVEM UUO,XCFBL ;NEW BASELINE 2379: CAMN UCHN,TEM ;CHECK TO SEE IF OLD MCG IS EMPTY 2380: JRST XCI1 ;NO NEED TO CLOSE AN EMPTY MCG 2381: CAIGE PROG,2(TEM) ;ROOM TO CLOSE THIS HERE? 2382: PUSHJ P,ADDNOD ;NO. MAKE ANOTHER NODE. 2383: JRST ES1.1B ;SET RETURN, SET UP FOR NEW CHB 2384: 2385: ;HERE FOR '177 '001 '044 - INSERT PAPER PAGE NUMBER. 2386: ES1.4: MOVE DAT,XGPPG2 2387: CAILE DAT,=99999 2388: JRST XCI1 ;FLUSH. 2389: MOVEM TAC,XGPAT0 2390: MOVEM TAC1,XGPAT1 2391: MOVEI TAC,(DAT) 2392: MOVE DAT,[POINT 7,XGPAT2] 2393: PUSHJ P,ES1.4B 2394: MOVEI TAC,XGPAT2 2395: MOVEI TAC1,5 2396: JRST XCI1 2397: ES1.4B: IDIVI TAC,=10 2398: HRLM TAC1,(P) 2399: JUMPE TAC,.+2 2400: PUSHJ P,ES1.4B 2401: HLRZ TAC,(P) 2402: ADDI TAC,"0" 2403: IDPB TAC,DAT 2404: POPJ P, 2405: 2406: ;HERE FOR '177 '1 '45 - SET AND PRINT HEADING 2407: ES1.5: MOVSI AC2,XGPHDB 2408: HLRZM AC2,XGPHDW ;CLEAR HEADING COUNT 2409: SETZM XGPHDB ;CLEAR HEADING BUFFER 2410: HRRI AC2,XGPHDB+1 2411: BLT AC2,XGPHDB+=25 ;CLEAR 130 CHARACTERS 2412: JSP AC3,XCIG ;GET A CHARACTER. THIS IS THE COUNT. 2413: MOVEI AC1,(DAT) ;KEEP THE COUNT. 2414: JUMPE AC1,XCI1 ;COUNT OF ZERO MEANS FLUSH HEADING. 2415: MOVE AC2,[POINT 7,XGPHDB] 2416: ES1.5A: JSP AC3,XCIG 2417: IDPB DAT,AC2 2418: SOJG AC1,ES1.5A ;DECREMENT COUNT AND LOOP UNLESS RUN OUT 2419: ANDI AC2,-1 ;GET THE ADDRESS ONLY 2420: SUBI AC2,XGPHDB-1 ;COMPUTE WORD COUNT 2421: MOVNI AC2,(AC2) 2422: HRLM AC2,XGPHDW 2423: MOVE DAT,MTB(TAC1) 2424: ANDM DAT,(TAC) ;CLEAR OUT THE TEXT WE'VE PROCESSED 2425: JSP AC3,BFNSET ;GIVE BACK SOME BUFFER SPACE 2426: MOVE TAC,XGPHDW ;READY FOR THE HEADING 2427: JRST XCIP2 ;SET DO THE HEADING. (OOF) 2428: 2429: ;HERE FOR '177 '1 '46 - START UNDERLINE. 2430: ES1.6: MOVEM J,XUSBEG ;STORE PRESENT COLUMN FOR START OF UNDERLINE 2431: JRST XCI1 ;DO MORE. 2432: 2433: ;HERE FOR '177 '002 - XGP ESCAPE 2 2434: ESC2: JSP AC3,XCIG ;GET ANOTHER CHARACTER 2435: CAIL DAT,100 ;SKIP IF INTERPRETED AS POSITIVE 2436: ORCMI DAT,177 ;EXTEND NEGATIVE SIGN 2437: ADD J,DAT ;DO FULL WORD ADD. 2438: JUMPGE J,XCI1CA ;NOW IT'S LIKE TAB OR CR 2439: MOVEI J,0 ;PREVENT BACKSPACE OFF LEFT END 2440: JRST XCI1CA ; 2441: 2442: GLOM: MOVEI AC1,0 ;ACCUMULATE MULTIPLE BYTES 2443: ;COUNT IN AC2, RETURNS IN AC1 2444: GLOM1: JSP AC3,XCIG ;GET A BYTE 2445: LSH AC1,7 2446: IORI AC1,(DAT) 2447: SOJG AC2,GLOM1 ;DECREMENT COUNT 2448: POPJ P, ;RETURN. 2449: 2450: ;HERE FOR '177 '003 - SET Y POSITION OF CURRENT TEXT LINE. 2451: ESC3: MOVEI AC2,2 ;GET 2 BYTES 2452: PUSHJ P,GLOM ;GOBBLE GOBBLE 2453: MOVEM AC1,XCYPOS ;SET CURRENT Y POSITION. 2454: JRST XCI1 ;COMPILE MORE. 2455: 2456: ;HERE FOR '177 '004 2457: ESC4A: CONO PI,PION ;HERE TO WAIT FOR A NODE. 2458: JSR X2DISP 2459: ESC4: CONO PI,PIOFF 2460: SKIPN UUO,XVNFL ;GOBBLE FROM VECTOR NODE FREE LIST. 2461: JRST ESC4A ;WAIT. 2462: MOVE DAT,(UUO) 2463: MOVEM DAT,XVNFL 2464: CONO PI,PION ;UUO NOW POINTS TO THE NEW NODE. 2465: SETZM (UUO) 2466: MOVEI AC2,2 ;2 BYTES OF Y0 2467: PUSHJ P,GLOM 2468: MOVEM AC1,1(UUO) ;STORE Y0 2469: MOVEI AC2,2 ;2 BYTES OF X0 2470: PUSHJ P,GLOM 2471: ANDI AC1,7777 ;RESTRICT X0 TO RANGE 2472: HRLZM AC1,2(UUO) ;STORE X0 2473: MOVEI AC2,3 ;3 BYTES OF DX 2474: PUSHJ P,GLOM 2475: TLNE AC1,4 ;SIGN BIT? 2476: TLO AC1,777770 ;SIGN EXTEND. 2477: LSH AC1,11 ;SHIFT 9 BITS 2478: MOVEM AC1,4(UUO) ;STUFF DX 2479: MOVEI AC2,2 ;2 BYTES OF N 2480: PUSHJ P,GLOM 2481: HRRM AC1,2(UUO) ;STORE N 2482: MOVEI AC2,2 2483: PUSHJ P,GLOM 2484: ANDI AC1,7777 ;REASONABLENESS 2485: IORI AC1,SETN ;TURN ON THE RIGHT BITS 2486: MOVEM AC1,3(UUO) ;STORE WIDTH. 2487: MOVEM UUO,XVNODE ;STORE NODE ADDRESS. 2488: SKIPN DAT,XGPPS2 ;SKIP UNLESS SPECIAL PAGE HACK 2489: JRST ESC4B ;SPECIAL PAGE HACK. LEAVE IT ALONE. 2490: ADD DAT,XGPPS1 ;SEE IF WE HAVE A PAGE TOO LONG 2491: CAML DAT,1(UUO) ;SKIP IF WE'VE LOST 2492: JRST ESC4B ;WE'RE OK SO FAR. 2493: PUSHJ P,XERR13 ;THIS WILL SET THE ERROR CODE 2494: ESC4X: SETZM 1(UUO) ;(THIS WILL FORCE OOO ERROR) 2495: JRST XCI1F ;QUEUE THIS TEXT NODE. 2496: ESC4B: HRRZ DAT,2(UUO) ;GET N 2497: HLLZ AC1,2(UUO) ;GET X0 2498: IMUL DAT,4(UUO) ;N*DX 2499: ADD DAT,AC1 ;+X0 2500: CAMG DAT,[7777,,-1] ;OR TO FAR T'OTHER WAY 2501: JUMPGE DAT,XCI1F ;SMALL ENOUGH. JUMP IF BIG ENOUGH 2502: PUSHJ P,XERR14 ;LOSE - ILLEGAL VECTOR PARAMETERS 2503: SETZM 4(UUO) ;SET DX TO 0 2504: HLLZS 2(UUO) ;SET N TO 0 2505: JRST ESC4X ;GO FORCE OOO ERROR. 2507: ; HERE FOR A 'NORMAL' CHARACTER 2508: XCI2A: ADD DAT,XFTCAD ;ADD BASE OF TABLE 2509: SKIPN AC3,1(DAT) ;SKIP IF THERE'S A CHARACTER THERE. 2510: JRST XCI1 ;NONE THERE GET ANOTHER CHARACTER 2511: LDB AC2,[POINT 1,(AC3),10] 2512: JUMPN AC2,XCI2AW ;JUMP IF THIS IS A LEFT-KERN CHARACTER 2513: XCI2AX: CAML J,XGPRMR ;ARE WE ABOUT TO OVERSTEP RIGHT MARGIN? 2514: AOJA TAC1,XCI1D ;YES. PUT BACK THIS CHARACTER. 2515: CAME DSER,TEM ;SKIP IF THIS IS A NEW SUBGROUP 2516: JRST XCI2B ;NOT NEW 2517: CAME UCHN,TEM ;SKIP IF THIS IS A NEW MCG 2518: JRST XCI2AZ ;NO. JUST NEW SUBGROUP 2519: JUMPE TEM,XCI2AC ;JUMP IF THERE ARE NO MCG'S 2520: SKIPL AC2,XLBL ;ARE THERE OTHER CHB'S YET? 2521: JRST XCI2AA ;YES. 2522: XCI2AC: MOVE AC2,XCFBL 2523: MOVEM AC2,XLBL 2524: XCI2AA: SUB AC2,XCFBL ;SUBTRACT TO FIND BASELINE OFFSET. 2525: JUMPL AC2,XCI2AB ;NEW BASELINE IS BIGGER (DEEPER) 2526: MOVEI AC3,(AC2) 2527: ADD AC3,XCFH 2528: JSP AC1,SCHB ;SEARCH FOR A BLOCK THAT'S RIGHT 2529: SKIPGE AC2,XLBL ;LINE BASE-LINE SET YET? 2530: MOVE AC2,XCFBL ;NOT YET. DO SO NOW. 2531: MOVEM AC2,XLBL 2532: JRST XCI2AY 2533: 2534: XCI2AB: MOVM AC3,AC2 ;THE AMOUNT TO ADD TO ALL PRIOR COMMANDS. 2535: ADDM AC3,XHMAX ;MAX HEIGHT MUST BE INCREASED 2536: MOVE AC1,XCFBL 2537: MOVEM AC1,XLBL ;SET NEW LINE BASE-LINE 2538: JSP AC1,OFFCHB ;SET OFFSET IN ALL PRIOR COMMANDS 2539: HRRZ AC3,XCFH ;SET MAX FOR THIS TERM 2540: MOVEI AC2,0 ;MIN 2541: JSP AC1,ACHB ;ADD A NEW COMMAND HEADER BLOCK 2542: 2543: XCI2AY: CAIGE PROG,2(TEM) 2544: PUSHJ P,ADDNOD 2545: PUSH TEM,[CONO XGP,SETX] 2546: ADDM J,(TEM) ;SET COLUMN SELECTOR. 2547: XCI2AZ: HLRO AC3,1(DAT) ;GET THE CHARACTER WIDTH (WORDS) 2548: ADDI AC3,(PROG) 2549: CAIGE AC3,3(TEM) ;ROOM FOR JSP,PTR,data,JRST? 2550: PUSHJ P,ADDNOD ;NO. ADD A NEW NODE. 2551: PUSH TEM,[JSP AC3,SCAN] ;STUFF COMMAND INTO BUFFER. 2552: MOVE DSER,TEM 2553: MOVEI UUO,2(TEM) 2554: PUSH TEM,UUO 2555: MOVE AC3,1(DAT) ;GET THE DATUM AGAIN. 2556: XCI2B: HLRO AC2,AC3 ;GET SIZE OF THIS ITEM. 2557: ADDI AC2,(PROG) 2558: CAIGE AC2,1(TEM) ;WILL THIS FIT? 2559: JRST XCI2AZ ;NO. START A NEW NODE. 2560: HLLZ AC2,AC3 2561: ADDM AC2,1(DSER) 2562: LDB AC1,[POINT 9,(AC3),8] ;GET THE WIDTH 2563: ADDI J,(AC1) ;ADD THE WIDTH TO THE COLUMN COUNTER 2564: LDB AC1,[POINT 1,(AC3),9] ;GET WIDTH KLUDGE BIT 2565: PUSH TEM,(AC3) ;STUFF POINTERS 2566: AOBJN AC3,.-1 2567: JUMPE AC1,XCI1 ;BACK TO GET ANOTHER UNLESS WIDTH KLUDGE 2568: JRST XCI1CA ;ELSE EXPLICITLY SET COLUMN POSITION. 2569: 2570: XCI2AW: AOSN XLFTKF ;LEFT-KERN FLAG SET? 2571: JRST XCI2AX ;YES. WE WERE THRU HERE LAST TIME 2572: SETOM XLFTKF 2573: LDB AC2,[POINT 9,-1(AC3),35] ;GET KERN-OFFSET 2574: SUBI J,(AC2) 2575: AOJA TAC1,XCI1CA ;GO SET THE COLUMN POSTION. PUT CHR BACK 2577: BEND XGPSER